From df03874ba90205d37e4d35a95eb1353b6fe43151 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Joan=20Lled=C3=B3?= <jlledom@member.fsf.org>
Date: Fri, 7 Sep 2018 09:21:48 +0200
Subject: [PATCH] Allow the use of external Sockets headers

    New macro LWIP_SOCKET_HEADERS can be used to replace
    LwIP sockets headers by OS's headers.

    By default LWIP_SOCKET_HEADERS==LWIP_SOCKET, when LWIP_SOCKET==1
    and LWIP_SOCKET_HEADERS==0, user must provide their custom headers
    by setting LWIP_INCLUDE_SOCKETS and LWIP_INCLUDE_INET.
---
 src/core/init.c                 |  13 -
 src/include/lwip/inet.h         | 127 +-------
 src/include/lwip/lwip_inet.h    | 169 ++++++++++
 src/include/lwip/lwip_sockets.h | 688 ++++++++++++++++++++++++++++++++++++++++
 src/include/lwip/opt.h          |   9 +
 src/include/lwip/sockets.h      | 645 +------------------------------------
 6 files changed, 875 insertions(+), 776 deletions(-)
 create mode 100644 src/include/lwip/lwip_inet.h
 create mode 100644 src/include/lwip/lwip_sockets.h

diff --git a/src/core/init.c b/src/core/init.c
index 34766019..6971b39f 100644
--- a/src/core/init.c
+++ b/src/core/init.c
@@ -237,19 +237,6 @@ PACK_STRUCT_END
 #error "NETCONN_MORE != TCP_WRITE_FLAG_MORE"
 #endif
 #endif /* LWIP_NETCONN && LWIP_TCP */
-#if LWIP_SOCKET
-/* Check that the SO_* socket options and SOF_* lwIP-internal flags match */
-#if SO_REUSEADDR != SOF_REUSEADDR
-#error "WARNING: SO_REUSEADDR != SOF_REUSEADDR"
-#endif
-#if SO_KEEPALIVE != SOF_KEEPALIVE
-#error "WARNING: SO_KEEPALIVE != SOF_KEEPALIVE"
-#endif
-#if SO_BROADCAST != SOF_BROADCAST
-#error "WARNING: SO_BROADCAST != SOF_BROADCAST"
-#endif
-#endif /* LWIP_SOCKET */
-
 
 /* Compile-time checks for deprecated options.
  */
diff --git a/src/include/lwip/inet.h b/src/include/lwip/inet.h
index 2982a0f4..5150dc18 100644
--- a/src/include/lwip/inet.h
+++ b/src/include/lwip/inet.h
@@ -1,5 +1,6 @@
 /**
  * @file
+ * Wrapper header
  * This file (together with sockets.h) aims to provide structs and functions from
  * - arpa/inet.h
  * - netinet/in.h
@@ -41,129 +42,11 @@
 #define LWIP_HDR_INET_H
 
 #include "lwip/opt.h"
-#include "lwip/def.h"
-#include "lwip/ip_addr.h"
-#include "lwip/ip6_addr.h"
 
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/* If your port already typedef's in_addr_t, define IN_ADDR_T_DEFINED
-   to prevent this code from redefining it. */
-#if !defined(in_addr_t) && !defined(IN_ADDR_T_DEFINED)
-typedef u32_t in_addr_t;
-#endif
-
-struct in_addr {
-  in_addr_t s_addr;
-};
-
-struct in6_addr {
-  union {
-    u32_t u32_addr[4];
-    u8_t  u8_addr[16];
-  } un;
-#define s6_addr  un.u8_addr
-};
-
-/** 255.255.255.255 */
-#define INADDR_NONE         IPADDR_NONE
-/** 127.0.0.1 */
-#define INADDR_LOOPBACK     IPADDR_LOOPBACK
-/** 0.0.0.0 */
-#define INADDR_ANY          IPADDR_ANY
-/** 255.255.255.255 */
-#define INADDR_BROADCAST    IPADDR_BROADCAST
-
-/** This macro can be used to initialize a variable of type struct in6_addr
-    to the IPv6 wildcard address. */
-#define IN6ADDR_ANY_INIT {{{0,0,0,0}}}
-/** This macro can be used to initialize a variable of type struct in6_addr
-    to the IPv6 loopback address. */
-#define IN6ADDR_LOOPBACK_INIT {{{0,0,0,PP_HTONL(1)}}}
-/** This variable is initialized by the system to contain the wildcard IPv6 address. */
-extern const struct in6_addr in6addr_any;
-
-/* Definitions of the bits in an (IPv4) Internet address integer.
-
-   On subnets, host and network parts are found according to
-   the subnet mask, not these masks.  */
-#define IN_CLASSA(a)        IP_CLASSA(a)
-#define IN_CLASSA_NET       IP_CLASSA_NET
-#define IN_CLASSA_NSHIFT    IP_CLASSA_NSHIFT
-#define IN_CLASSA_HOST      IP_CLASSA_HOST
-#define IN_CLASSA_MAX       IP_CLASSA_MAX
-
-#define IN_CLASSB(b)        IP_CLASSB(b)
-#define IN_CLASSB_NET       IP_CLASSB_NET
-#define IN_CLASSB_NSHIFT    IP_CLASSB_NSHIFT
-#define IN_CLASSB_HOST      IP_CLASSB_HOST
-#define IN_CLASSB_MAX       IP_CLASSB_MAX
-
-#define IN_CLASSC(c)        IP_CLASSC(c)
-#define IN_CLASSC_NET       IP_CLASSC_NET
-#define IN_CLASSC_NSHIFT    IP_CLASSC_NSHIFT
-#define IN_CLASSC_HOST      IP_CLASSC_HOST
-#define IN_CLASSC_MAX       IP_CLASSC_MAX
-
-#define IN_CLASSD(d)        IP_CLASSD(d)
-#define IN_CLASSD_NET       IP_CLASSD_NET     /* These ones aren't really */
-#define IN_CLASSD_NSHIFT    IP_CLASSD_NSHIFT  /*   net and host fields, but */
-#define IN_CLASSD_HOST      IP_CLASSD_HOST    /*   routing needn't know. */
-#define IN_CLASSD_MAX       IP_CLASSD_MAX
-
-#define IN_MULTICAST(a)     IP_MULTICAST(a)
-
-#define IN_EXPERIMENTAL(a)  IP_EXPERIMENTAL(a)
-#define IN_BADCLASS(a)      IP_BADCLASS(a)
-
-#define IN_LOOPBACKNET      IP_LOOPBACKNET
-
-
-#ifndef INET_ADDRSTRLEN
-#define INET_ADDRSTRLEN     IP4ADDR_STRLEN_MAX
-#endif
-#if LWIP_IPV6
-#ifndef INET6_ADDRSTRLEN
-#define INET6_ADDRSTRLEN    IP6ADDR_STRLEN_MAX
-#endif
-#endif
-
-#if LWIP_IPV4
-
-#define inet_addr_from_ip4addr(target_inaddr, source_ipaddr) ((target_inaddr)->s_addr = ip4_addr_get_u32(source_ipaddr))
-#define inet_addr_to_ip4addr(target_ipaddr, source_inaddr)   (ip4_addr_set_u32(target_ipaddr, (source_inaddr)->s_addr))
-
-/* directly map this to the lwip internal functions */
-#define inet_addr(cp)                   ipaddr_addr(cp)
-#define inet_aton(cp, addr)             ip4addr_aton(cp, (ip4_addr_t*)addr)
-#define inet_ntoa(addr)                 ip4addr_ntoa((const ip4_addr_t*)&(addr))
-#define inet_ntoa_r(addr, buf, buflen)  ip4addr_ntoa_r((const ip4_addr_t*)&(addr), buf, buflen)
-
-#endif /* LWIP_IPV4 */
-
-#if LWIP_IPV6
-#define inet6_addr_from_ip6addr(target_in6addr, source_ip6addr) {(target_in6addr)->un.u32_addr[0] = (source_ip6addr)->addr[0]; \
-                                                                 (target_in6addr)->un.u32_addr[1] = (source_ip6addr)->addr[1]; \
-                                                                 (target_in6addr)->un.u32_addr[2] = (source_ip6addr)->addr[2]; \
-                                                                 (target_in6addr)->un.u32_addr[3] = (source_ip6addr)->addr[3];}
-#define inet6_addr_to_ip6addr(target_ip6addr, source_in6addr)   {(target_ip6addr)->addr[0] = (source_in6addr)->un.u32_addr[0]; \
-                                                                 (target_ip6addr)->addr[1] = (source_in6addr)->un.u32_addr[1]; \
-                                                                 (target_ip6addr)->addr[2] = (source_in6addr)->un.u32_addr[2]; \
-                                                                 (target_ip6addr)->addr[3] = (source_in6addr)->un.u32_addr[3]; \
-                                                                 ip6_addr_clear_zone(target_ip6addr);}
-
-/* directly map this to the lwip internal functions */
-#define inet6_aton(cp, addr)            ip6addr_aton(cp, (ip6_addr_t*)addr)
-#define inet6_ntoa(addr)                ip6addr_ntoa((const ip6_addr_t*)&(addr))
-#define inet6_ntoa_r(addr, buf, buflen) ip6addr_ntoa_r((const ip6_addr_t*)&(addr), buf, buflen)
-
-#endif /* LWIP_IPV6 */
-
-
-#ifdef __cplusplus
-}
+#if LWIP_SOCKET_HEADERS
+#include "lwip/lwip_inet.h"
+#else
+#include LWIP_INCLUDE_INET
 #endif
 
 #endif /* LWIP_HDR_INET_H */
diff --git a/src/include/lwip/lwip_inet.h b/src/include/lwip/lwip_inet.h
new file mode 100644
index 00000000..d70a3602
--- /dev/null
+++ b/src/include/lwip/lwip_inet.h
@@ -0,0 +1,169 @@
+/**
+ * @file
+ * This file (together with sockets.h) aims to provide structs and functions from
+ * - arpa/inet.h
+ * - netinet/in.h
+ *
+ */
+
+/*
+ * Copyright (c) 2001-2004 Swedish Institute of Computer Science.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ *    this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ *    this list of conditions and the following disclaimer in the documentation
+ *    and/or other materials provided with the distribution.
+ * 3. The name of the author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
+ * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
+ * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
+ * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
+ * OF SUCH DAMAGE.
+ *
+ * This file is part of the lwIP TCP/IP stack.
+ *
+ * Author: Adam Dunkels <adam@sics.se>
+ *
+ */
+#ifndef LWIP_HDR_LWIP_INET_H
+#define LWIP_HDR_LWIP_INET_H
+
+#include "lwip/opt.h"
+#include "lwip/def.h"
+#include "lwip/ip_addr.h"
+#include "lwip/ip6_addr.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* If your port already typedef's in_addr_t, define IN_ADDR_T_DEFINED
+   to prevent this code from redefining it. */
+#if !defined(in_addr_t) && !defined(IN_ADDR_T_DEFINED)
+typedef u32_t in_addr_t;
+#endif
+
+struct in_addr {
+  in_addr_t s_addr;
+};
+
+struct in6_addr {
+  union {
+    u32_t u32_addr[4];
+    u8_t  u8_addr[16];
+  } un;
+#define s6_addr  un.u8_addr
+};
+
+/** 255.255.255.255 */
+#define INADDR_NONE         IPADDR_NONE
+/** 127.0.0.1 */
+#define INADDR_LOOPBACK     IPADDR_LOOPBACK
+/** 0.0.0.0 */
+#define INADDR_ANY          IPADDR_ANY
+/** 255.255.255.255 */
+#define INADDR_BROADCAST    IPADDR_BROADCAST
+
+/** This macro can be used to initialize a variable of type struct in6_addr
+    to the IPv6 wildcard address. */
+#define IN6ADDR_ANY_INIT {{{0,0,0,0}}}
+/** This macro can be used to initialize a variable of type struct in6_addr
+    to the IPv6 loopback address. */
+#define IN6ADDR_LOOPBACK_INIT {{{0,0,0,PP_HTONL(1)}}}
+/** This variable is initialized by the system to contain the wildcard IPv6 address. */
+extern const struct in6_addr in6addr_any;
+
+/* Definitions of the bits in an (IPv4) Internet address integer.
+
+   On subnets, host and network parts are found according to
+   the subnet mask, not these masks.  */
+#define IN_CLASSA(a)        IP_CLASSA(a)
+#define IN_CLASSA_NET       IP_CLASSA_NET
+#define IN_CLASSA_NSHIFT    IP_CLASSA_NSHIFT
+#define IN_CLASSA_HOST      IP_CLASSA_HOST
+#define IN_CLASSA_MAX       IP_CLASSA_MAX
+
+#define IN_CLASSB(b)        IP_CLASSB(b)
+#define IN_CLASSB_NET       IP_CLASSB_NET
+#define IN_CLASSB_NSHIFT    IP_CLASSB_NSHIFT
+#define IN_CLASSB_HOST      IP_CLASSB_HOST
+#define IN_CLASSB_MAX       IP_CLASSB_MAX
+
+#define IN_CLASSC(c)        IP_CLASSC(c)
+#define IN_CLASSC_NET       IP_CLASSC_NET
+#define IN_CLASSC_NSHIFT    IP_CLASSC_NSHIFT
+#define IN_CLASSC_HOST      IP_CLASSC_HOST
+#define IN_CLASSC_MAX       IP_CLASSC_MAX
+
+#define IN_CLASSD(d)        IP_CLASSD(d)
+#define IN_CLASSD_NET       IP_CLASSD_NET     /* These ones aren't really */
+#define IN_CLASSD_NSHIFT    IP_CLASSD_NSHIFT  /*   net and host fields, but */
+#define IN_CLASSD_HOST      IP_CLASSD_HOST    /*   routing needn't know. */
+#define IN_CLASSD_MAX       IP_CLASSD_MAX
+
+#define IN_MULTICAST(a)     IP_MULTICAST(a)
+
+#define IN_EXPERIMENTAL(a)  IP_EXPERIMENTAL(a)
+#define IN_BADCLASS(a)      IP_BADCLASS(a)
+
+#define IN_LOOPBACKNET      IP_LOOPBACKNET
+
+
+#ifndef INET_ADDRSTRLEN
+#define INET_ADDRSTRLEN     IP4ADDR_STRLEN_MAX
+#endif
+#if LWIP_IPV6
+#ifndef INET6_ADDRSTRLEN
+#define INET6_ADDRSTRLEN    IP6ADDR_STRLEN_MAX
+#endif
+#endif
+
+#if LWIP_IPV4
+
+#define inet_addr_from_ip4addr(target_inaddr, source_ipaddr) ((target_inaddr)->s_addr = ip4_addr_get_u32(source_ipaddr))
+#define inet_addr_to_ip4addr(target_ipaddr, source_inaddr)   (ip4_addr_set_u32(target_ipaddr, (source_inaddr)->s_addr))
+
+/* directly map this to the lwip internal functions */
+#define inet_addr(cp)                   ipaddr_addr(cp)
+#define inet_aton(cp, addr)             ip4addr_aton(cp, (ip4_addr_t*)addr)
+#define inet_ntoa(addr)                 ip4addr_ntoa((const ip4_addr_t*)&(addr))
+#define inet_ntoa_r(addr, buf, buflen)  ip4addr_ntoa_r((const ip4_addr_t*)&(addr), buf, buflen)
+
+#endif /* LWIP_IPV4 */
+
+#if LWIP_IPV6
+#define inet6_addr_from_ip6addr(target_in6addr, source_ip6addr) {(target_in6addr)->un.u32_addr[0] = (source_ip6addr)->addr[0]; \
+                                                                 (target_in6addr)->un.u32_addr[1] = (source_ip6addr)->addr[1]; \
+                                                                 (target_in6addr)->un.u32_addr[2] = (source_ip6addr)->addr[2]; \
+                                                                 (target_in6addr)->un.u32_addr[3] = (source_ip6addr)->addr[3];}
+#define inet6_addr_to_ip6addr(target_ip6addr, source_in6addr)   {(target_ip6addr)->addr[0] = (source_in6addr)->un.u32_addr[0]; \
+                                                                 (target_ip6addr)->addr[1] = (source_in6addr)->un.u32_addr[1]; \
+                                                                 (target_ip6addr)->addr[2] = (source_in6addr)->un.u32_addr[2]; \
+                                                                 (target_ip6addr)->addr[3] = (source_in6addr)->un.u32_addr[3]; \
+                                                                 ip6_addr_clear_zone(target_ip6addr);}
+
+/* directly map this to the lwip internal functions */
+#define inet6_aton(cp, addr)            ip6addr_aton(cp, (ip6_addr_t*)addr)
+#define inet6_ntoa(addr)                ip6addr_ntoa((const ip6_addr_t*)&(addr))
+#define inet6_ntoa_r(addr, buf, buflen) ip6addr_ntoa_r((const ip6_addr_t*)&(addr), buf, buflen)
+
+#endif /* LWIP_IPV6 */
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* LWIP_HDR_LWIP_INET_H */
diff --git a/src/include/lwip/lwip_sockets.h b/src/include/lwip/lwip_sockets.h
new file mode 100644
index 00000000..9e9406d0
--- /dev/null
+++ b/src/include/lwip/lwip_sockets.h
@@ -0,0 +1,688 @@
+/**
+ * @file
+ * Socket API (to be used from non-TCPIP threads)
+ */
+
+/*
+ * Copyright (c) 2001-2004 Swedish Institute of Computer Science.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ *    this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ *    this list of conditions and the following disclaimer in the documentation
+ *    and/or other materials provided with the distribution.
+ * 3. The name of the author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
+ * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
+ * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
+ * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
+ * OF SUCH DAMAGE.
+ *
+ * This file is part of the lwIP TCP/IP stack.
+ *
+ * Author: Adam Dunkels <adam@sics.se>
+ *
+ */
+
+
+#ifndef LWIP_HDR_LWIP_SOCKETS_H
+#define LWIP_HDR_LWIP_SOCKETS_H
+
+#include "lwip/opt.h"
+
+#if LWIP_SOCKET /* don't build if not configured for use in lwipopts.h */
+
+#include "lwip/ip_addr.h"
+#include "lwip/netif.h"
+#include "lwip/err.h"
+#include "lwip/inet.h"
+#include "lwip/errno.h"
+
+#include <string.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* If your port already typedef's sa_family_t, define SA_FAMILY_T_DEFINED
+   to prevent this code from redefining it. */
+#if !defined(sa_family_t) && !defined(SA_FAMILY_T_DEFINED)
+typedef u8_t sa_family_t;
+#endif
+/* If your port already typedef's in_port_t, define IN_PORT_T_DEFINED
+   to prevent this code from redefining it. */
+#if !defined(in_port_t) && !defined(IN_PORT_T_DEFINED)
+typedef u16_t in_port_t;
+#endif
+
+#if LWIP_IPV4
+/* members are in network byte order */
+struct sockaddr_in {
+  u8_t            sin_len;
+  sa_family_t     sin_family;
+  in_port_t       sin_port;
+  struct in_addr  sin_addr;
+#define SIN_ZERO_LEN 8
+  char            sin_zero[SIN_ZERO_LEN];
+};
+#endif /* LWIP_IPV4 */
+
+#if LWIP_IPV6
+struct sockaddr_in6 {
+  u8_t            sin6_len;      /* length of this structure    */
+  sa_family_t     sin6_family;   /* AF_INET6                    */
+  in_port_t       sin6_port;     /* Transport layer port #      */
+  u32_t           sin6_flowinfo; /* IPv6 flow information       */
+  struct in6_addr sin6_addr;     /* IPv6 address                */
+  u32_t           sin6_scope_id; /* Set of interfaces for scope */
+};
+#endif /* LWIP_IPV6 */
+
+struct sockaddr {
+  u8_t        sa_len;
+  sa_family_t sa_family;
+  char        sa_data[14];
+};
+
+struct sockaddr_storage {
+  u8_t        s2_len;
+  sa_family_t ss_family;
+  char        s2_data1[2];
+  u32_t       s2_data2[3];
+#if LWIP_IPV6
+  u32_t       s2_data3[3];
+#endif /* LWIP_IPV6 */
+};
+
+/* If your port already typedef's socklen_t, define SOCKLEN_T_DEFINED
+   to prevent this code from redefining it. */
+#if !defined(socklen_t) && !defined(SOCKLEN_T_DEFINED)
+typedef u32_t socklen_t;
+#endif
+
+#if !defined IOV_MAX
+#define IOV_MAX 0xFFFF
+#elif IOV_MAX > 0xFFFF
+#error "IOV_MAX larger than supported by LwIP"
+#endif /* IOV_MAX */
+
+#if !defined(iovec)
+struct iovec {
+  void  *iov_base;
+  size_t iov_len;
+};
+#endif
+
+struct msghdr {
+  void         *msg_name;
+  socklen_t     msg_namelen;
+  struct iovec *msg_iov;
+  int           msg_iovlen;
+  void         *msg_control;
+  socklen_t     msg_controllen;
+  int           msg_flags;
+};
+
+/* struct msghdr->msg_flags bit field values */
+#define MSG_TRUNC   0x04
+#define MSG_CTRUNC  0x08
+
+/* RFC 3542, Section 20: Ancillary Data */
+struct cmsghdr {
+  socklen_t  cmsg_len;   /* number of bytes, including header */
+  int        cmsg_level; /* originating protocol */
+  int        cmsg_type;  /* protocol-specific type */
+};
+/* Data section follows header and possible padding, typically referred to as
+      unsigned char cmsg_data[]; */
+
+/* cmsg header/data alignment. NOTE: we align to native word size (double word
+size on 16-bit arch) so structures are not placed at an unaligned address.
+16-bit arch needs double word to ensure 32-bit alignment because socklen_t
+could be 32 bits. If we ever have cmsg data with a 64-bit variable, alignment
+will need to increase long long */
+#define ALIGN_H(size) (((size) + sizeof(long) - 1U) & ~(sizeof(long)-1U))
+#define ALIGN_D(size) ALIGN_H(size)
+
+#define CMSG_FIRSTHDR(mhdr) \
+          ((mhdr)->msg_controllen >= sizeof(struct cmsghdr) ? \
+           (struct cmsghdr *)(mhdr)->msg_control : \
+           (struct cmsghdr *)NULL)
+
+#define CMSG_NXTHDR(mhdr, cmsg) \
+        (((cmsg) == NULL) ? CMSG_FIRSTHDR(mhdr) : \
+         (((u8_t *)(cmsg) + ALIGN_H((cmsg)->cmsg_len) \
+                            + ALIGN_D(sizeof(struct cmsghdr)) > \
+           (u8_t *)((mhdr)->msg_control) + (mhdr)->msg_controllen) ? \
+          (struct cmsghdr *)NULL : \
+          (struct cmsghdr *)((void*)((u8_t *)(cmsg) + \
+                                      ALIGN_H((cmsg)->cmsg_len)))))
+
+#define CMSG_DATA(cmsg) ((void*)((u8_t *)(cmsg) + \
+                         ALIGN_D(sizeof(struct cmsghdr))))
+
+#define CMSG_SPACE(length) (ALIGN_D(sizeof(struct cmsghdr)) + \
+                            ALIGN_H(length))
+
+#define CMSG_LEN(length) (ALIGN_D(sizeof(struct cmsghdr)) + \
+                           length)
+
+/* Set socket options argument */
+#define IFNAMSIZ NETIF_NAMESIZE
+struct ifreq {
+  char ifr_name[IFNAMSIZ]; /* Interface name */
+};
+
+/* Socket protocol types (TCP/UDP/RAW) */
+#define SOCK_STREAM     1
+#define SOCK_DGRAM      2
+#define SOCK_RAW        3
+
+/*
+ * Option flags per-socket. These must match the SOF_ flags in ip.h (checked in init.c)
+ */
+#define SO_REUSEADDR   0x0004 /* Allow local address reuse */
+#define SO_KEEPALIVE   0x0008 /* keep connections alive */
+#define SO_BROADCAST   0x0020 /* permit to send and to receive broadcast messages (see IP_SOF_BROADCAST option) */
+
+
+/*
+ * Additional options, not kept in so_options.
+ */
+#define SO_DEBUG        0x0001 /* Unimplemented: turn on debugging info recording */
+#define SO_ACCEPTCONN   0x0002 /* socket has had listen() */
+#define SO_DONTROUTE    0x0010 /* Unimplemented: just use interface addresses */
+#define SO_USELOOPBACK  0x0040 /* Unimplemented: bypass hardware when possible */
+#define SO_LINGER       0x0080 /* linger on close if data present */
+#define SO_DONTLINGER   ((int)(~SO_LINGER))
+#define SO_OOBINLINE    0x0100 /* Unimplemented: leave received OOB data in line */
+#define SO_REUSEPORT    0x0200 /* Unimplemented: allow local address & port reuse */
+#define SO_SNDBUF       0x1001 /* Unimplemented: send buffer size */
+#define SO_RCVBUF       0x1002 /* receive buffer size */
+#define SO_SNDLOWAT     0x1003 /* Unimplemented: send low-water mark */
+#define SO_RCVLOWAT     0x1004 /* Unimplemented: receive low-water mark */
+#define SO_SNDTIMEO     0x1005 /* send timeout */
+#define SO_RCVTIMEO     0x1006 /* receive timeout */
+#define SO_ERROR        0x1007 /* get error status and clear */
+#define SO_TYPE         0x1008 /* get socket type */
+#define SO_CONTIMEO     0x1009 /* Unimplemented: connect timeout */
+#define SO_NO_CHECK     0x100a /* don't create UDP checksum */
+#define SO_BINDTODEVICE 0x100b /* bind to device */
+
+/*
+ * Structure used for manipulating linger option.
+ */
+struct linger {
+  int l_onoff;                /* option on/off */
+  int l_linger;               /* linger time in seconds */
+};
+
+/*
+ * Level number for (get/set)sockopt() to apply to socket itself.
+ */
+#define  SOL_SOCKET  0xfff    /* options for socket level */
+
+
+#define AF_UNSPEC       0
+#define AF_INET         2
+#if LWIP_IPV6
+#define AF_INET6        10
+#else /* LWIP_IPV6 */
+#define AF_INET6        AF_UNSPEC
+#endif /* LWIP_IPV6 */
+#define PF_INET         AF_INET
+#define PF_INET6        AF_INET6
+#define PF_UNSPEC       AF_UNSPEC
+
+#define IPPROTO_IP      0
+#define IPPROTO_ICMP    1
+#define IPPROTO_TCP     6
+#define IPPROTO_UDP     17
+#if LWIP_IPV6
+#define IPPROTO_IPV6    41
+#define IPPROTO_ICMPV6  58
+#endif /* LWIP_IPV6 */
+#define IPPROTO_UDPLITE 136
+#define IPPROTO_RAW     255
+
+/* Flags we can use with send and recv. */
+#define MSG_PEEK       0x01    /* Peeks at an incoming message */
+#define MSG_WAITALL    0x02    /* Unimplemented: Requests that the function block until the full amount of data requested can be returned */
+#define MSG_OOB        0x04    /* Unimplemented: Requests out-of-band data. The significance and semantics of out-of-band data are protocol-specific */
+#define MSG_DONTWAIT   0x08    /* Nonblocking i/o for this operation only */
+#define MSG_MORE       0x10    /* Sender will send more */
+#define MSG_NOSIGNAL   0x20    /* Uninmplemented: Requests not to send the SIGPIPE signal if an attempt to send is made on a stream-oriented socket that is no longer connected. */
+
+
+/*
+ * Options for level IPPROTO_IP
+ */
+#define IP_TOS             1
+#define IP_TTL             2
+#define IP_PKTINFO         8
+
+#if LWIP_TCP
+/*
+ * Options for level IPPROTO_TCP
+ */
+#define TCP_NODELAY    0x01    /* don't delay send to coalesce packets */
+#define TCP_KEEPALIVE  0x02    /* send KEEPALIVE probes when idle for pcb->keep_idle milliseconds */
+#define TCP_KEEPIDLE   0x03    /* set pcb->keep_idle  - Same as TCP_KEEPALIVE, but use seconds for get/setsockopt */
+#define TCP_KEEPINTVL  0x04    /* set pcb->keep_intvl - Use seconds for get/setsockopt */
+#define TCP_KEEPCNT    0x05    /* set pcb->keep_cnt   - Use number of probes sent for get/setsockopt */
+#endif /* LWIP_TCP */
+
+#if LWIP_IPV6
+/*
+ * Options for level IPPROTO_IPV6
+ */
+#define IPV6_CHECKSUM       7  /* RFC3542: calculate and insert the ICMPv6 checksum for raw sockets. */
+#define IPV6_V6ONLY         27 /* RFC3493: boolean control to restrict AF_INET6 sockets to IPv6 communications only. */
+#endif /* LWIP_IPV6 */
+
+#if LWIP_UDP && LWIP_UDPLITE
+/*
+ * Options for level IPPROTO_UDPLITE
+ */
+#define UDPLITE_SEND_CSCOV 0x01 /* sender checksum coverage */
+#define UDPLITE_RECV_CSCOV 0x02 /* minimal receiver checksum coverage */
+#endif /* LWIP_UDP && LWIP_UDPLITE*/
+
+
+#if LWIP_MULTICAST_TX_OPTIONS
+/*
+ * Options and types for UDP multicast traffic handling
+ */
+#define IP_MULTICAST_TTL   5
+#define IP_MULTICAST_IF    6
+#define IP_MULTICAST_LOOP  7
+#endif /* LWIP_MULTICAST_TX_OPTIONS */
+
+#if LWIP_IGMP
+/*
+ * Options and types related to multicast membership
+ */
+#define IP_ADD_MEMBERSHIP  3
+#define IP_DROP_MEMBERSHIP 4
+
+typedef struct ip_mreq {
+    struct in_addr imr_multiaddr; /* IP multicast address of group */
+    struct in_addr imr_interface; /* local IP address of interface */
+} ip_mreq;
+#endif /* LWIP_IGMP */
+
+#if LWIP_IPV4
+struct in_pktinfo {
+  unsigned int   ipi_ifindex;  /* Interface index */
+  struct in_addr ipi_addr;     /* Destination (from header) address */
+};
+#endif /* LWIP_IPV4 */
+
+#if LWIP_IPV6_MLD
+/*
+ * Options and types related to IPv6 multicast membership
+ */
+#define IPV6_JOIN_GROUP      12
+#define IPV6_ADD_MEMBERSHIP  IPV6_JOIN_GROUP
+#define IPV6_LEAVE_GROUP     13
+#define IPV6_DROP_MEMBERSHIP IPV6_LEAVE_GROUP
+
+typedef struct ipv6_mreq {
+  struct in6_addr ipv6mr_multiaddr; /*  IPv6 multicast addr */
+  unsigned int    ipv6mr_interface; /*  interface index, or 0 */
+} ipv6_mreq;
+#endif /* LWIP_IPV6_MLD */
+
+/*
+ * The Type of Service provides an indication of the abstract
+ * parameters of the quality of service desired.  These parameters are
+ * to be used to guide the selection of the actual service parameters
+ * when transmitting a datagram through a particular network.  Several
+ * networks offer service precedence, which somehow treats high
+ * precedence traffic as more important than other traffic (generally
+ * by accepting only traffic above a certain precedence at time of high
+ * load).  The major choice is a three way tradeoff between low-delay,
+ * high-reliability, and high-throughput.
+ * The use of the Delay, Throughput, and Reliability indications may
+ * increase the cost (in some sense) of the service.  In many networks
+ * better performance for one of these parameters is coupled with worse
+ * performance on another.  Except for very unusual cases at most two
+ * of these three indications should be set.
+ */
+#define IPTOS_TOS_MASK          0x1E
+#define IPTOS_TOS(tos)          ((tos) & IPTOS_TOS_MASK)
+#define IPTOS_LOWDELAY          0x10
+#define IPTOS_THROUGHPUT        0x08
+#define IPTOS_RELIABILITY       0x04
+#define IPTOS_LOWCOST           0x02
+#define IPTOS_MINCOST           IPTOS_LOWCOST
+
+/*
+ * The Network Control precedence designation is intended to be used
+ * within a network only.  The actual use and control of that
+ * designation is up to each network. The Internetwork Control
+ * designation is intended for use by gateway control originators only.
+ * If the actual use of these precedence designations is of concern to
+ * a particular network, it is the responsibility of that network to
+ * control the access to, and use of, those precedence designations.
+ */
+#define IPTOS_PREC_MASK                 0xe0
+#define IPTOS_PREC(tos)                ((tos) & IPTOS_PREC_MASK)
+#define IPTOS_PREC_NETCONTROL           0xe0
+#define IPTOS_PREC_INTERNETCONTROL      0xc0
+#define IPTOS_PREC_CRITIC_ECP           0xa0
+#define IPTOS_PREC_FLASHOVERRIDE        0x80
+#define IPTOS_PREC_FLASH                0x60
+#define IPTOS_PREC_IMMEDIATE            0x40
+#define IPTOS_PREC_PRIORITY             0x20
+#define IPTOS_PREC_ROUTINE              0x00
+
+
+/*
+ * Commands for ioctlsocket(),  taken from the BSD file fcntl.h.
+ * lwip_ioctl only supports FIONREAD and FIONBIO, for now
+ *
+ * Ioctl's have the command encoded in the lower word,
+ * and the size of any in or out parameters in the upper
+ * word.  The high 2 bits of the upper word are used
+ * to encode the in/out status of the parameter; for now
+ * we restrict parameters to at most 128 bytes.
+ */
+#if !defined(FIONREAD) || !defined(FIONBIO)
+#define IOCPARM_MASK    0x7fU           /* parameters must be < 128 bytes */
+#define IOC_VOID        0x20000000UL    /* no parameters */
+#define IOC_OUT         0x40000000UL    /* copy out parameters */
+#define IOC_IN          0x80000000UL    /* copy in parameters */
+#define IOC_INOUT       (IOC_IN|IOC_OUT)
+                                        /* 0x20000000 distinguishes new &
+                                           old ioctl's */
+#define _IO(x,y)        ((long)(IOC_VOID|((x)<<8)|(y)))
+
+#define _IOR(x,y,t)     ((long)(IOC_OUT|((sizeof(t)&IOCPARM_MASK)<<16)|((x)<<8)|(y)))
+
+#define _IOW(x,y,t)     ((long)(IOC_IN|((sizeof(t)&IOCPARM_MASK)<<16)|((x)<<8)|(y)))
+#endif /* !defined(FIONREAD) || !defined(FIONBIO) */
+
+#ifndef FIONREAD
+#define FIONREAD    _IOR('f', 127, unsigned long) /* get # bytes to read */
+#endif
+#ifndef FIONBIO
+#define FIONBIO     _IOW('f', 126, unsigned long) /* set/clear non-blocking i/o */
+#endif
+
+/* Socket I/O Controls: unimplemented */
+#ifndef SIOCSHIWAT
+#define SIOCSHIWAT  _IOW('s',  0, unsigned long)  /* set high watermark */
+#define SIOCGHIWAT  _IOR('s',  1, unsigned long)  /* get high watermark */
+#define SIOCSLOWAT  _IOW('s',  2, unsigned long)  /* set low watermark */
+#define SIOCGLOWAT  _IOR('s',  3, unsigned long)  /* get low watermark */
+#define SIOCATMARK  _IOR('s',  7, unsigned long)  /* at oob mark? */
+#endif
+
+/* commands for fnctl */
+#ifndef F_GETFL
+#define F_GETFL 3
+#endif
+#ifndef F_SETFL
+#define F_SETFL 4
+#endif
+
+/* File status flags and file access modes for fnctl,
+   these are bits in an int. */
+#ifndef O_NONBLOCK
+#define O_NONBLOCK  1 /* nonblocking I/O */
+#endif
+#ifndef O_NDELAY
+#define O_NDELAY    O_NONBLOCK /* same as O_NONBLOCK, for compatibility */
+#endif
+#ifndef O_RDONLY
+#define O_RDONLY    2
+#endif
+#ifndef O_WRONLY
+#define O_WRONLY    4
+#endif
+#ifndef O_RDWR
+#define O_RDWR      (O_RDONLY|O_WRONLY)
+#endif
+
+#ifndef SHUT_RD
+  #define SHUT_RD   0
+  #define SHUT_WR   1
+  #define SHUT_RDWR 2
+#endif
+
+/* FD_SET used for lwip_select */
+#ifndef FD_SET
+#undef  FD_SETSIZE
+/* Make FD_SETSIZE match NUM_SOCKETS in socket.c */
+#define FD_SETSIZE    MEMP_NUM_NETCONN
+#define LWIP_SELECT_MAXNFDS (FD_SETSIZE + LWIP_SOCKET_OFFSET)
+#define FDSETSAFESET(n, code) do { \
+  if (((n) - LWIP_SOCKET_OFFSET < MEMP_NUM_NETCONN) && (((int)(n) - LWIP_SOCKET_OFFSET) >= 0)) { \
+  code; }} while(0)
+#define FDSETSAFEGET(n, code) (((n) - LWIP_SOCKET_OFFSET < MEMP_NUM_NETCONN) && (((int)(n) - LWIP_SOCKET_OFFSET) >= 0) ?\
+  (code) : 0)
+#define FD_SET(n, p)  FDSETSAFESET(n, (p)->fd_bits[((n)-LWIP_SOCKET_OFFSET)/8] = (u8_t)((p)->fd_bits[((n)-LWIP_SOCKET_OFFSET)/8] |  (1 << (((n)-LWIP_SOCKET_OFFSET) & 7))))
+#define FD_CLR(n, p)  FDSETSAFESET(n, (p)->fd_bits[((n)-LWIP_SOCKET_OFFSET)/8] = (u8_t)((p)->fd_bits[((n)-LWIP_SOCKET_OFFSET)/8] & ~(1 << (((n)-LWIP_SOCKET_OFFSET) & 7))))
+#define FD_ISSET(n,p) FDSETSAFEGET(n, (p)->fd_bits[((n)-LWIP_SOCKET_OFFSET)/8] &   (1 << (((n)-LWIP_SOCKET_OFFSET) & 7)))
+#define FD_ZERO(p)    memset((void*)(p), 0, sizeof(*(p)))
+
+typedef struct fd_set
+{
+  unsigned char fd_bits [(FD_SETSIZE+7)/8];
+} fd_set;
+
+#elif FD_SETSIZE < (LWIP_SOCKET_OFFSET + MEMP_NUM_NETCONN)
+#error "external FD_SETSIZE too small for number of sockets"
+#else
+#define LWIP_SELECT_MAXNFDS FD_SETSIZE
+#endif /* FD_SET */
+
+/* poll-related defines and types */
+/* @todo: find a better way to guard the definition of these defines and types if already defined */
+#if !defined(POLLIN) && !defined(POLLOUT)
+#define POLLIN     0x1
+#define POLLOUT    0x2
+#define POLLERR    0x4
+#define POLLNVAL   0x8
+/* Below values are unimplemented */
+#define POLLRDNORM 0x10
+#define POLLRDBAND 0x20
+#define POLLPRI    0x40
+#define POLLWRNORM 0x80
+#define POLLWRBAND 0x100
+#define POLLHUP    0x200
+typedef unsigned int nfds_t;
+struct pollfd
+{
+  int fd;
+  short events;
+  short revents;
+};
+#endif
+
+/** LWIP_TIMEVAL_PRIVATE: if you want to use the struct timeval provided
+ * by your system, set this to 0 and include <sys/time.h> in cc.h */
+#ifndef LWIP_TIMEVAL_PRIVATE
+#define LWIP_TIMEVAL_PRIVATE 1
+#endif
+
+#if LWIP_TIMEVAL_PRIVATE
+struct timeval {
+  long    tv_sec;         /* seconds */
+  long    tv_usec;        /* and microseconds */
+};
+#endif /* LWIP_TIMEVAL_PRIVATE */
+
+#define lwip_socket_init() /* Compatibility define, no init needed. */
+void lwip_socket_thread_init(void); /* LWIP_NETCONN_SEM_PER_THREAD==1: initialize thread-local semaphore */
+void lwip_socket_thread_cleanup(void); /* LWIP_NETCONN_SEM_PER_THREAD==1: destroy thread-local semaphore */
+
+#if LWIP_COMPAT_SOCKETS == 2
+/* This helps code parsers/code completion by not having the COMPAT functions as defines */
+#define lwip_accept       accept
+#define lwip_bind         bind
+#define lwip_shutdown     shutdown
+#define lwip_getpeername  getpeername
+#define lwip_getsockname  getsockname
+#define lwip_setsockopt   setsockopt
+#define lwip_getsockopt   getsockopt
+#define lwip_close        closesocket
+#define lwip_connect      connect
+#define lwip_listen       listen
+#define lwip_recv         recv
+#define lwip_recvmsg      recvmsg
+#define lwip_recvfrom     recvfrom
+#define lwip_send         send
+#define lwip_sendmsg      sendmsg
+#define lwip_sendto       sendto
+#define lwip_socket       socket
+#if LWIP_SOCKET_SELECT
+#define lwip_select       select
+#endif
+#if LWIP_SOCKET_POLL
+#define lwip_poll         poll
+#endif
+#define lwip_ioctl        ioctlsocket
+#define lwip_inet_ntop    inet_ntop
+#define lwip_inet_pton    inet_pton
+
+#if LWIP_POSIX_SOCKETS_IO_NAMES
+#define lwip_read         read
+#define lwip_readv        readv
+#define lwip_write        write
+#define lwip_writev       writev
+#undef lwip_close
+#define lwip_close        close
+#define closesocket(s)    close(s)
+int fcntl(int s, int cmd, ...);
+#undef lwip_ioctl
+#define lwip_ioctl        ioctl
+#define ioctlsocket       ioctl
+#endif /* LWIP_POSIX_SOCKETS_IO_NAMES */
+#endif /* LWIP_COMPAT_SOCKETS == 2 */
+
+int lwip_accept(int s, struct sockaddr *addr, socklen_t *addrlen);
+int lwip_bind(int s, const struct sockaddr *name, socklen_t namelen);
+int lwip_shutdown(int s, int how);
+int lwip_getpeername (int s, struct sockaddr *name, socklen_t *namelen);
+int lwip_getsockname (int s, struct sockaddr *name, socklen_t *namelen);
+int lwip_getsockopt (int s, int level, int optname, void *optval, socklen_t *optlen);
+int lwip_setsockopt (int s, int level, int optname, const void *optval, socklen_t optlen);
+ int lwip_close(int s);
+int lwip_connect(int s, const struct sockaddr *name, socklen_t namelen);
+int lwip_listen(int s, int backlog);
+ssize_t lwip_recv(int s, void *mem, size_t len, int flags);
+ssize_t lwip_read(int s, void *mem, size_t len);
+ssize_t lwip_readv(int s, const struct iovec *iov, int iovcnt);
+ssize_t lwip_recvfrom(int s, void *mem, size_t len, int flags,
+      struct sockaddr *from, socklen_t *fromlen);
+ssize_t lwip_recvmsg(int s, struct msghdr *message, int flags);
+ssize_t lwip_send(int s, const void *dataptr, size_t size, int flags);
+ssize_t lwip_sendmsg(int s, const struct msghdr *message, int flags);
+ssize_t lwip_sendto(int s, const void *dataptr, size_t size, int flags,
+    const struct sockaddr *to, socklen_t tolen);
+int lwip_socket(int domain, int type, int protocol);
+ssize_t lwip_write(int s, const void *dataptr, size_t size);
+ssize_t lwip_writev(int s, const struct iovec *iov, int iovcnt);
+#if LWIP_SOCKET_SELECT
+int lwip_select(int maxfdp1, fd_set *readset, fd_set *writeset, fd_set *exceptset,
+                struct timeval *timeout);
+#endif
+#if LWIP_SOCKET_POLL
+int lwip_poll(struct pollfd *fds, nfds_t nfds, int timeout);
+#endif
+int lwip_ioctl(int s, long cmd, void *argp);
+int lwip_fcntl(int s, int cmd, int val);
+const char *lwip_inet_ntop(int af, const void *src, char *dst, socklen_t size);
+int lwip_inet_pton(int af, const char *src, void *dst);
+
+#if LWIP_COMPAT_SOCKETS
+#if LWIP_COMPAT_SOCKETS != 2
+/** @ingroup socket */
+#define accept(s,addr,addrlen)                    lwip_accept(s,addr,addrlen)
+/** @ingroup socket */
+#define bind(s,name,namelen)                      lwip_bind(s,name,namelen)
+/** @ingroup socket */
+#define shutdown(s,how)                           lwip_shutdown(s,how)
+/** @ingroup socket */
+#define getpeername(s,name,namelen)               lwip_getpeername(s,name,namelen)
+/** @ingroup socket */
+#define getsockname(s,name,namelen)               lwip_getsockname(s,name,namelen)
+/** @ingroup socket */
+#define setsockopt(s,level,optname,opval,optlen)  lwip_setsockopt(s,level,optname,opval,optlen)
+/** @ingroup socket */
+#define getsockopt(s,level,optname,opval,optlen)  lwip_getsockopt(s,level,optname,opval,optlen)
+/** @ingroup socket */
+#define closesocket(s)                            lwip_close(s)
+/** @ingroup socket */
+#define connect(s,name,namelen)                   lwip_connect(s,name,namelen)
+/** @ingroup socket */
+#define listen(s,backlog)                         lwip_listen(s,backlog)
+/** @ingroup socket */
+#define recv(s,mem,len,flags)                     lwip_recv(s,mem,len,flags)
+/** @ingroup socket */
+#define recvmsg(s,message,flags)                  lwip_recvmsg(s,message,flags)
+/** @ingroup socket */
+#define recvfrom(s,mem,len,flags,from,fromlen)    lwip_recvfrom(s,mem,len,flags,from,fromlen)
+/** @ingroup socket */
+#define send(s,dataptr,size,flags)                lwip_send(s,dataptr,size,flags)
+/** @ingroup socket */
+#define sendmsg(s,message,flags)                  lwip_sendmsg(s,message,flags)
+/** @ingroup socket */
+#define sendto(s,dataptr,size,flags,to,tolen)     lwip_sendto(s,dataptr,size,flags,to,tolen)
+/** @ingroup socket */
+#define socket(domain,type,protocol)              lwip_socket(domain,type,protocol)
+#if LWIP_SOCKET_SELECT
+/** @ingroup socket */
+#define select(maxfdp1,readset,writeset,exceptset,timeout)     lwip_select(maxfdp1,readset,writeset,exceptset,timeout)
+#endif
+#if LWIP_SOCKET_POLL
+/** @ingroup socket */
+#define poll(fds,nfds,timeout)                    lwip_poll(fds,nfds,timeout)
+#endif
+/** @ingroup socket */
+#define ioctlsocket(s,cmd,argp)                   lwip_ioctl(s,cmd,argp)
+/** @ingroup socket */
+#define inet_ntop(af,src,dst,size)                lwip_inet_ntop(af,src,dst,size)
+/** @ingroup socket */
+#define inet_pton(af,src,dst)                     lwip_inet_pton(af,src,dst)
+
+#if LWIP_POSIX_SOCKETS_IO_NAMES
+/** @ingroup socket */
+#define read(s,mem,len)                           lwip_read(s,mem,len)
+/** @ingroup socket */
+#define readv(s,iov,iovcnt)                       lwip_readv(s,iov,iovcnt)
+/** @ingroup socket */
+#define write(s,dataptr,len)                      lwip_write(s,dataptr,len)
+/** @ingroup socket */
+#define writev(s,iov,iovcnt)                      lwip_writev(s,iov,iovcnt)
+/** @ingroup socket */
+#define close(s)                                  lwip_close(s)
+/** @ingroup socket */
+#define fcntl(s,cmd,val)                          lwip_fcntl(s,cmd,val)
+/** @ingroup socket */
+#define ioctl(s,cmd,argp)                         lwip_ioctl(s,cmd,argp)
+#endif /* LWIP_POSIX_SOCKETS_IO_NAMES */
+#endif /* LWIP_COMPAT_SOCKETS != 2 */
+
+#endif /* LWIP_COMPAT_SOCKETS */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* LWIP_SOCKET */
+
+#endif /* LWIP_HDR_LWIP_SOCKETS_H */
diff --git a/src/include/lwip/opt.h b/src/include/lwip/opt.h
index f5c8f931..6b93f2cb 100644
--- a/src/include/lwip/opt.h
+++ b/src/include/lwip/opt.h
@@ -1979,6 +1979,15 @@
 #endif
 
 /**
+ * LWIP_SOCKET_HEADERS==LWIP_SOCKET: Use LwIP's provided socket headers.
+ * When set to 0, user must provide its own socket headers by setting the
+ * values for LWIP_INCLUDE_SOCKETS and LWIP_INCLUDE_INET.
+ */
+#if !defined LWIP_SOCKET_HEADERS || defined __DOXYGEN__
+#define LWIP_SOCKET_HEADERS              LWIP_SOCKET
+#endif
+
+/**
  * LWIP_TCP_KEEPALIVE==1: Enable TCP_KEEPIDLE, TCP_KEEPINTVL and TCP_KEEPCNT
  * options processing. Note that TCP_KEEPIDLE and TCP_KEEPINTVL have to be set
  * in seconds. (does not require sockets.c, and will affect tcp.c)
diff --git a/src/include/lwip/sockets.h b/src/include/lwip/sockets.h
index d70d36c4..0283eff6 100644
--- a/src/include/lwip/sockets.h
+++ b/src/include/lwip/sockets.h
@@ -1,5 +1,6 @@
 /**
  * @file
+ * Wrapper header
  * Socket API (to be used from non-TCPIP threads)
  */
 
@@ -41,648 +42,10 @@
 
 #include "lwip/opt.h"
 
-#if LWIP_SOCKET /* don't build if not configured for use in lwipopts.h */
-
-#include "lwip/ip_addr.h"
-#include "lwip/netif.h"
-#include "lwip/err.h"
-#include "lwip/inet.h"
-#include "lwip/errno.h"
-
-#include <string.h>
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/* If your port already typedef's sa_family_t, define SA_FAMILY_T_DEFINED
-   to prevent this code from redefining it. */
-#if !defined(sa_family_t) && !defined(SA_FAMILY_T_DEFINED)
-typedef u8_t sa_family_t;
-#endif
-/* If your port already typedef's in_port_t, define IN_PORT_T_DEFINED
-   to prevent this code from redefining it. */
-#if !defined(in_port_t) && !defined(IN_PORT_T_DEFINED)
-typedef u16_t in_port_t;
-#endif
-
-#if LWIP_IPV4
-/* members are in network byte order */
-struct sockaddr_in {
-  u8_t            sin_len;
-  sa_family_t     sin_family;
-  in_port_t       sin_port;
-  struct in_addr  sin_addr;
-#define SIN_ZERO_LEN 8
-  char            sin_zero[SIN_ZERO_LEN];
-};
-#endif /* LWIP_IPV4 */
-
-#if LWIP_IPV6
-struct sockaddr_in6 {
-  u8_t            sin6_len;      /* length of this structure    */
-  sa_family_t     sin6_family;   /* AF_INET6                    */
-  in_port_t       sin6_port;     /* Transport layer port #      */
-  u32_t           sin6_flowinfo; /* IPv6 flow information       */
-  struct in6_addr sin6_addr;     /* IPv6 address                */
-  u32_t           sin6_scope_id; /* Set of interfaces for scope */
-};
-#endif /* LWIP_IPV6 */
-
-struct sockaddr {
-  u8_t        sa_len;
-  sa_family_t sa_family;
-  char        sa_data[14];
-};
-
-struct sockaddr_storage {
-  u8_t        s2_len;
-  sa_family_t ss_family;
-  char        s2_data1[2];
-  u32_t       s2_data2[3];
-#if LWIP_IPV6
-  u32_t       s2_data3[3];
-#endif /* LWIP_IPV6 */
-};
-
-/* If your port already typedef's socklen_t, define SOCKLEN_T_DEFINED
-   to prevent this code from redefining it. */
-#if !defined(socklen_t) && !defined(SOCKLEN_T_DEFINED)
-typedef u32_t socklen_t;
-#endif
-
-#if !defined IOV_MAX
-#define IOV_MAX 0xFFFF
-#elif IOV_MAX > 0xFFFF
-#error "IOV_MAX larger than supported by LwIP"
-#endif /* IOV_MAX */
-
-#if !defined(iovec)
-struct iovec {
-  void  *iov_base;
-  size_t iov_len;
-};
-#endif
-
-struct msghdr {
-  void         *msg_name;
-  socklen_t     msg_namelen;
-  struct iovec *msg_iov;
-  int           msg_iovlen;
-  void         *msg_control;
-  socklen_t     msg_controllen;
-  int           msg_flags;
-};
-
-/* struct msghdr->msg_flags bit field values */
-#define MSG_TRUNC   0x04
-#define MSG_CTRUNC  0x08
-
-/* RFC 3542, Section 20: Ancillary Data */
-struct cmsghdr {
-  socklen_t  cmsg_len;   /* number of bytes, including header */
-  int        cmsg_level; /* originating protocol */
-  int        cmsg_type;  /* protocol-specific type */
-};
-/* Data section follows header and possible padding, typically referred to as
-      unsigned char cmsg_data[]; */
-
-/* cmsg header/data alignment. NOTE: we align to native word size (double word
-size on 16-bit arch) so structures are not placed at an unaligned address.
-16-bit arch needs double word to ensure 32-bit alignment because socklen_t
-could be 32 bits. If we ever have cmsg data with a 64-bit variable, alignment
-will need to increase long long */
-#define ALIGN_H(size) (((size) + sizeof(long) - 1U) & ~(sizeof(long)-1U))
-#define ALIGN_D(size) ALIGN_H(size)
-
-#define CMSG_FIRSTHDR(mhdr) \
-          ((mhdr)->msg_controllen >= sizeof(struct cmsghdr) ? \
-           (struct cmsghdr *)(mhdr)->msg_control : \
-           (struct cmsghdr *)NULL)
-
-#define CMSG_NXTHDR(mhdr, cmsg) \
-        (((cmsg) == NULL) ? CMSG_FIRSTHDR(mhdr) : \
-         (((u8_t *)(cmsg) + ALIGN_H((cmsg)->cmsg_len) \
-                            + ALIGN_D(sizeof(struct cmsghdr)) > \
-           (u8_t *)((mhdr)->msg_control) + (mhdr)->msg_controllen) ? \
-          (struct cmsghdr *)NULL : \
-          (struct cmsghdr *)((void*)((u8_t *)(cmsg) + \
-                                      ALIGN_H((cmsg)->cmsg_len)))))
-
-#define CMSG_DATA(cmsg) ((void*)((u8_t *)(cmsg) + \
-                         ALIGN_D(sizeof(struct cmsghdr))))
-
-#define CMSG_SPACE(length) (ALIGN_D(sizeof(struct cmsghdr)) + \
-                            ALIGN_H(length))
-
-#define CMSG_LEN(length) (ALIGN_D(sizeof(struct cmsghdr)) + \
-                           length)
-
-/* Set socket options argument */
-#define IFNAMSIZ NETIF_NAMESIZE
-struct ifreq {
-  char ifr_name[IFNAMSIZ]; /* Interface name */
-};
-
-/* Socket protocol types (TCP/UDP/RAW) */
-#define SOCK_STREAM     1
-#define SOCK_DGRAM      2
-#define SOCK_RAW        3
-
-/*
- * Option flags per-socket. These must match the SOF_ flags in ip.h (checked in init.c)
- */
-#define SO_REUSEADDR   0x0004 /* Allow local address reuse */
-#define SO_KEEPALIVE   0x0008 /* keep connections alive */
-#define SO_BROADCAST   0x0020 /* permit to send and to receive broadcast messages (see IP_SOF_BROADCAST option) */
-
-
-/*
- * Additional options, not kept in so_options.
- */
-#define SO_DEBUG        0x0001 /* Unimplemented: turn on debugging info recording */
-#define SO_ACCEPTCONN   0x0002 /* socket has had listen() */
-#define SO_DONTROUTE    0x0010 /* Unimplemented: just use interface addresses */
-#define SO_USELOOPBACK  0x0040 /* Unimplemented: bypass hardware when possible */
-#define SO_LINGER       0x0080 /* linger on close if data present */
-#define SO_DONTLINGER   ((int)(~SO_LINGER))
-#define SO_OOBINLINE    0x0100 /* Unimplemented: leave received OOB data in line */
-#define SO_REUSEPORT    0x0200 /* Unimplemented: allow local address & port reuse */
-#define SO_SNDBUF       0x1001 /* Unimplemented: send buffer size */
-#define SO_RCVBUF       0x1002 /* receive buffer size */
-#define SO_SNDLOWAT     0x1003 /* Unimplemented: send low-water mark */
-#define SO_RCVLOWAT     0x1004 /* Unimplemented: receive low-water mark */
-#define SO_SNDTIMEO     0x1005 /* send timeout */
-#define SO_RCVTIMEO     0x1006 /* receive timeout */
-#define SO_ERROR        0x1007 /* get error status and clear */
-#define SO_TYPE         0x1008 /* get socket type */
-#define SO_CONTIMEO     0x1009 /* Unimplemented: connect timeout */
-#define SO_NO_CHECK     0x100a /* don't create UDP checksum */
-#define SO_BINDTODEVICE 0x100b /* bind to device */
-
-/*
- * Structure used for manipulating linger option.
- */
-struct linger {
-  int l_onoff;                /* option on/off */
-  int l_linger;               /* linger time in seconds */
-};
-
-/*
- * Level number for (get/set)sockopt() to apply to socket itself.
- */
-#define  SOL_SOCKET  0xfff    /* options for socket level */
-
-
-#define AF_UNSPEC       0
-#define AF_INET         2
-#if LWIP_IPV6
-#define AF_INET6        10
-#else /* LWIP_IPV6 */
-#define AF_INET6        AF_UNSPEC
-#endif /* LWIP_IPV6 */
-#define PF_INET         AF_INET
-#define PF_INET6        AF_INET6
-#define PF_UNSPEC       AF_UNSPEC
-
-#define IPPROTO_IP      0
-#define IPPROTO_ICMP    1
-#define IPPROTO_TCP     6
-#define IPPROTO_UDP     17
-#if LWIP_IPV6
-#define IPPROTO_IPV6    41
-#define IPPROTO_ICMPV6  58
-#endif /* LWIP_IPV6 */
-#define IPPROTO_UDPLITE 136
-#define IPPROTO_RAW     255
-
-/* Flags we can use with send and recv. */
-#define MSG_PEEK       0x01    /* Peeks at an incoming message */
-#define MSG_WAITALL    0x02    /* Unimplemented: Requests that the function block until the full amount of data requested can be returned */
-#define MSG_OOB        0x04    /* Unimplemented: Requests out-of-band data. The significance and semantics of out-of-band data are protocol-specific */
-#define MSG_DONTWAIT   0x08    /* Nonblocking i/o for this operation only */
-#define MSG_MORE       0x10    /* Sender will send more */
-#define MSG_NOSIGNAL   0x20    /* Uninmplemented: Requests not to send the SIGPIPE signal if an attempt to send is made on a stream-oriented socket that is no longer connected. */
-
-
-/*
- * Options for level IPPROTO_IP
- */
-#define IP_TOS             1
-#define IP_TTL             2
-#define IP_PKTINFO         8
-
-#if LWIP_TCP
-/*
- * Options for level IPPROTO_TCP
- */
-#define TCP_NODELAY    0x01    /* don't delay send to coalesce packets */
-#define TCP_KEEPALIVE  0x02    /* send KEEPALIVE probes when idle for pcb->keep_idle milliseconds */
-#define TCP_KEEPIDLE   0x03    /* set pcb->keep_idle  - Same as TCP_KEEPALIVE, but use seconds for get/setsockopt */
-#define TCP_KEEPINTVL  0x04    /* set pcb->keep_intvl - Use seconds for get/setsockopt */
-#define TCP_KEEPCNT    0x05    /* set pcb->keep_cnt   - Use number of probes sent for get/setsockopt */
-#endif /* LWIP_TCP */
-
-#if LWIP_IPV6
-/*
- * Options for level IPPROTO_IPV6
- */
-#define IPV6_CHECKSUM       7  /* RFC3542: calculate and insert the ICMPv6 checksum for raw sockets. */
-#define IPV6_V6ONLY         27 /* RFC3493: boolean control to restrict AF_INET6 sockets to IPv6 communications only. */
-#endif /* LWIP_IPV6 */
-
-#if LWIP_UDP && LWIP_UDPLITE
-/*
- * Options for level IPPROTO_UDPLITE
- */
-#define UDPLITE_SEND_CSCOV 0x01 /* sender checksum coverage */
-#define UDPLITE_RECV_CSCOV 0x02 /* minimal receiver checksum coverage */
-#endif /* LWIP_UDP && LWIP_UDPLITE*/
-
-
-#if LWIP_MULTICAST_TX_OPTIONS
-/*
- * Options and types for UDP multicast traffic handling
- */
-#define IP_MULTICAST_TTL   5
-#define IP_MULTICAST_IF    6
-#define IP_MULTICAST_LOOP  7
-#endif /* LWIP_MULTICAST_TX_OPTIONS */
-
-#if LWIP_IGMP
-/*
- * Options and types related to multicast membership
- */
-#define IP_ADD_MEMBERSHIP  3
-#define IP_DROP_MEMBERSHIP 4
-
-typedef struct ip_mreq {
-    struct in_addr imr_multiaddr; /* IP multicast address of group */
-    struct in_addr imr_interface; /* local IP address of interface */
-} ip_mreq;
-#endif /* LWIP_IGMP */
-
-#if LWIP_IPV4
-struct in_pktinfo {
-  unsigned int   ipi_ifindex;  /* Interface index */
-  struct in_addr ipi_addr;     /* Destination (from header) address */
-};
-#endif /* LWIP_IPV4 */
-
-#if LWIP_IPV6_MLD
-/*
- * Options and types related to IPv6 multicast membership
- */
-#define IPV6_JOIN_GROUP      12
-#define IPV6_ADD_MEMBERSHIP  IPV6_JOIN_GROUP
-#define IPV6_LEAVE_GROUP     13
-#define IPV6_DROP_MEMBERSHIP IPV6_LEAVE_GROUP
-
-typedef struct ipv6_mreq {
-  struct in6_addr ipv6mr_multiaddr; /*  IPv6 multicast addr */
-  unsigned int    ipv6mr_interface; /*  interface index, or 0 */
-} ipv6_mreq;
-#endif /* LWIP_IPV6_MLD */
-
-/*
- * The Type of Service provides an indication of the abstract
- * parameters of the quality of service desired.  These parameters are
- * to be used to guide the selection of the actual service parameters
- * when transmitting a datagram through a particular network.  Several
- * networks offer service precedence, which somehow treats high
- * precedence traffic as more important than other traffic (generally
- * by accepting only traffic above a certain precedence at time of high
- * load).  The major choice is a three way tradeoff between low-delay,
- * high-reliability, and high-throughput.
- * The use of the Delay, Throughput, and Reliability indications may
- * increase the cost (in some sense) of the service.  In many networks
- * better performance for one of these parameters is coupled with worse
- * performance on another.  Except for very unusual cases at most two
- * of these three indications should be set.
- */
-#define IPTOS_TOS_MASK          0x1E
-#define IPTOS_TOS(tos)          ((tos) & IPTOS_TOS_MASK)
-#define IPTOS_LOWDELAY          0x10
-#define IPTOS_THROUGHPUT        0x08
-#define IPTOS_RELIABILITY       0x04
-#define IPTOS_LOWCOST           0x02
-#define IPTOS_MINCOST           IPTOS_LOWCOST
-
-/*
- * The Network Control precedence designation is intended to be used
- * within a network only.  The actual use and control of that
- * designation is up to each network. The Internetwork Control
- * designation is intended for use by gateway control originators only.
- * If the actual use of these precedence designations is of concern to
- * a particular network, it is the responsibility of that network to
- * control the access to, and use of, those precedence designations.
- */
-#define IPTOS_PREC_MASK                 0xe0
-#define IPTOS_PREC(tos)                ((tos) & IPTOS_PREC_MASK)
-#define IPTOS_PREC_NETCONTROL           0xe0
-#define IPTOS_PREC_INTERNETCONTROL      0xc0
-#define IPTOS_PREC_CRITIC_ECP           0xa0
-#define IPTOS_PREC_FLASHOVERRIDE        0x80
-#define IPTOS_PREC_FLASH                0x60
-#define IPTOS_PREC_IMMEDIATE            0x40
-#define IPTOS_PREC_PRIORITY             0x20
-#define IPTOS_PREC_ROUTINE              0x00
-
-
-/*
- * Commands for ioctlsocket(),  taken from the BSD file fcntl.h.
- * lwip_ioctl only supports FIONREAD and FIONBIO, for now
- *
- * Ioctl's have the command encoded in the lower word,
- * and the size of any in or out parameters in the upper
- * word.  The high 2 bits of the upper word are used
- * to encode the in/out status of the parameter; for now
- * we restrict parameters to at most 128 bytes.
- */
-#if !defined(FIONREAD) || !defined(FIONBIO)
-#define IOCPARM_MASK    0x7fU           /* parameters must be < 128 bytes */
-#define IOC_VOID        0x20000000UL    /* no parameters */
-#define IOC_OUT         0x40000000UL    /* copy out parameters */
-#define IOC_IN          0x80000000UL    /* copy in parameters */
-#define IOC_INOUT       (IOC_IN|IOC_OUT)
-                                        /* 0x20000000 distinguishes new &
-                                           old ioctl's */
-#define _IO(x,y)        ((long)(IOC_VOID|((x)<<8)|(y)))
-
-#define _IOR(x,y,t)     ((long)(IOC_OUT|((sizeof(t)&IOCPARM_MASK)<<16)|((x)<<8)|(y)))
-
-#define _IOW(x,y,t)     ((long)(IOC_IN|((sizeof(t)&IOCPARM_MASK)<<16)|((x)<<8)|(y)))
-#endif /* !defined(FIONREAD) || !defined(FIONBIO) */
-
-#ifndef FIONREAD
-#define FIONREAD    _IOR('f', 127, unsigned long) /* get # bytes to read */
-#endif
-#ifndef FIONBIO
-#define FIONBIO     _IOW('f', 126, unsigned long) /* set/clear non-blocking i/o */
-#endif
-
-/* Socket I/O Controls: unimplemented */
-#ifndef SIOCSHIWAT
-#define SIOCSHIWAT  _IOW('s',  0, unsigned long)  /* set high watermark */
-#define SIOCGHIWAT  _IOR('s',  1, unsigned long)  /* get high watermark */
-#define SIOCSLOWAT  _IOW('s',  2, unsigned long)  /* set low watermark */
-#define SIOCGLOWAT  _IOR('s',  3, unsigned long)  /* get low watermark */
-#define SIOCATMARK  _IOR('s',  7, unsigned long)  /* at oob mark? */
-#endif
-
-/* commands for fnctl */
-#ifndef F_GETFL
-#define F_GETFL 3
-#endif
-#ifndef F_SETFL
-#define F_SETFL 4
-#endif
-
-/* File status flags and file access modes for fnctl,
-   these are bits in an int. */
-#ifndef O_NONBLOCK
-#define O_NONBLOCK  1 /* nonblocking I/O */
-#endif
-#ifndef O_NDELAY
-#define O_NDELAY    O_NONBLOCK /* same as O_NONBLOCK, for compatibility */
-#endif
-#ifndef O_RDONLY
-#define O_RDONLY    2
-#endif
-#ifndef O_WRONLY
-#define O_WRONLY    4
-#endif
-#ifndef O_RDWR
-#define O_RDWR      (O_RDONLY|O_WRONLY)
-#endif
-
-#ifndef SHUT_RD
-  #define SHUT_RD   0
-  #define SHUT_WR   1
-  #define SHUT_RDWR 2
-#endif
-
-/* FD_SET used for lwip_select */
-#ifndef FD_SET
-#undef  FD_SETSIZE
-/* Make FD_SETSIZE match NUM_SOCKETS in socket.c */
-#define FD_SETSIZE    MEMP_NUM_NETCONN
-#define LWIP_SELECT_MAXNFDS (FD_SETSIZE + LWIP_SOCKET_OFFSET)
-#define FDSETSAFESET(n, code) do { \
-  if (((n) - LWIP_SOCKET_OFFSET < MEMP_NUM_NETCONN) && (((int)(n) - LWIP_SOCKET_OFFSET) >= 0)) { \
-  code; }} while(0)
-#define FDSETSAFEGET(n, code) (((n) - LWIP_SOCKET_OFFSET < MEMP_NUM_NETCONN) && (((int)(n) - LWIP_SOCKET_OFFSET) >= 0) ?\
-  (code) : 0)
-#define FD_SET(n, p)  FDSETSAFESET(n, (p)->fd_bits[((n)-LWIP_SOCKET_OFFSET)/8] = (u8_t)((p)->fd_bits[((n)-LWIP_SOCKET_OFFSET)/8] |  (1 << (((n)-LWIP_SOCKET_OFFSET) & 7))))
-#define FD_CLR(n, p)  FDSETSAFESET(n, (p)->fd_bits[((n)-LWIP_SOCKET_OFFSET)/8] = (u8_t)((p)->fd_bits[((n)-LWIP_SOCKET_OFFSET)/8] & ~(1 << (((n)-LWIP_SOCKET_OFFSET) & 7))))
-#define FD_ISSET(n,p) FDSETSAFEGET(n, (p)->fd_bits[((n)-LWIP_SOCKET_OFFSET)/8] &   (1 << (((n)-LWIP_SOCKET_OFFSET) & 7)))
-#define FD_ZERO(p)    memset((void*)(p), 0, sizeof(*(p)))
-
-typedef struct fd_set
-{
-  unsigned char fd_bits [(FD_SETSIZE+7)/8];
-} fd_set;
-
-#elif FD_SETSIZE < (LWIP_SOCKET_OFFSET + MEMP_NUM_NETCONN)
-#error "external FD_SETSIZE too small for number of sockets"
+#if LWIP_SOCKET_HEADERS
+#include "lwip/lwip_sockets.h"
 #else
-#define LWIP_SELECT_MAXNFDS FD_SETSIZE
-#endif /* FD_SET */
-
-/* poll-related defines and types */
-/* @todo: find a better way to guard the definition of these defines and types if already defined */
-#if !defined(POLLIN) && !defined(POLLOUT)
-#define POLLIN     0x1
-#define POLLOUT    0x2
-#define POLLERR    0x4
-#define POLLNVAL   0x8
-/* Below values are unimplemented */
-#define POLLRDNORM 0x10
-#define POLLRDBAND 0x20
-#define POLLPRI    0x40
-#define POLLWRNORM 0x80
-#define POLLWRBAND 0x100
-#define POLLHUP    0x200
-typedef unsigned int nfds_t;
-struct pollfd
-{
-  int fd;
-  short events;
-  short revents;
-};
-#endif
-
-/** LWIP_TIMEVAL_PRIVATE: if you want to use the struct timeval provided
- * by your system, set this to 0 and include <sys/time.h> in cc.h */
-#ifndef LWIP_TIMEVAL_PRIVATE
-#define LWIP_TIMEVAL_PRIVATE 1
-#endif
-
-#if LWIP_TIMEVAL_PRIVATE
-struct timeval {
-  long    tv_sec;         /* seconds */
-  long    tv_usec;        /* and microseconds */
-};
-#endif /* LWIP_TIMEVAL_PRIVATE */
-
-#define lwip_socket_init() /* Compatibility define, no init needed. */
-void lwip_socket_thread_init(void); /* LWIP_NETCONN_SEM_PER_THREAD==1: initialize thread-local semaphore */
-void lwip_socket_thread_cleanup(void); /* LWIP_NETCONN_SEM_PER_THREAD==1: destroy thread-local semaphore */
-
-#if LWIP_COMPAT_SOCKETS == 2
-/* This helps code parsers/code completion by not having the COMPAT functions as defines */
-#define lwip_accept       accept
-#define lwip_bind         bind
-#define lwip_shutdown     shutdown
-#define lwip_getpeername  getpeername
-#define lwip_getsockname  getsockname
-#define lwip_setsockopt   setsockopt
-#define lwip_getsockopt   getsockopt
-#define lwip_close        closesocket
-#define lwip_connect      connect
-#define lwip_listen       listen
-#define lwip_recv         recv
-#define lwip_recvmsg      recvmsg
-#define lwip_recvfrom     recvfrom
-#define lwip_send         send
-#define lwip_sendmsg      sendmsg
-#define lwip_sendto       sendto
-#define lwip_socket       socket
-#if LWIP_SOCKET_SELECT
-#define lwip_select       select
-#endif
-#if LWIP_SOCKET_POLL
-#define lwip_poll         poll
-#endif
-#define lwip_ioctl        ioctlsocket
-#define lwip_inet_ntop    inet_ntop
-#define lwip_inet_pton    inet_pton
-
-#if LWIP_POSIX_SOCKETS_IO_NAMES
-#define lwip_read         read
-#define lwip_readv        readv
-#define lwip_write        write
-#define lwip_writev       writev
-#undef lwip_close
-#define lwip_close        close
-#define closesocket(s)    close(s)
-int fcntl(int s, int cmd, ...);
-#undef lwip_ioctl
-#define lwip_ioctl        ioctl
-#define ioctlsocket       ioctl
-#endif /* LWIP_POSIX_SOCKETS_IO_NAMES */
-#endif /* LWIP_COMPAT_SOCKETS == 2 */
-
-int lwip_accept(int s, struct sockaddr *addr, socklen_t *addrlen);
-int lwip_bind(int s, const struct sockaddr *name, socklen_t namelen);
-int lwip_shutdown(int s, int how);
-int lwip_getpeername (int s, struct sockaddr *name, socklen_t *namelen);
-int lwip_getsockname (int s, struct sockaddr *name, socklen_t *namelen);
-int lwip_getsockopt (int s, int level, int optname, void *optval, socklen_t *optlen);
-int lwip_setsockopt (int s, int level, int optname, const void *optval, socklen_t optlen);
- int lwip_close(int s);
-int lwip_connect(int s, const struct sockaddr *name, socklen_t namelen);
-int lwip_listen(int s, int backlog);
-ssize_t lwip_recv(int s, void *mem, size_t len, int flags);
-ssize_t lwip_read(int s, void *mem, size_t len);
-ssize_t lwip_readv(int s, const struct iovec *iov, int iovcnt);
-ssize_t lwip_recvfrom(int s, void *mem, size_t len, int flags,
-      struct sockaddr *from, socklen_t *fromlen);
-ssize_t lwip_recvmsg(int s, struct msghdr *message, int flags);
-ssize_t lwip_send(int s, const void *dataptr, size_t size, int flags);
-ssize_t lwip_sendmsg(int s, const struct msghdr *message, int flags);
-ssize_t lwip_sendto(int s, const void *dataptr, size_t size, int flags,
-    const struct sockaddr *to, socklen_t tolen);
-int lwip_socket(int domain, int type, int protocol);
-ssize_t lwip_write(int s, const void *dataptr, size_t size);
-ssize_t lwip_writev(int s, const struct iovec *iov, int iovcnt);
-#if LWIP_SOCKET_SELECT
-int lwip_select(int maxfdp1, fd_set *readset, fd_set *writeset, fd_set *exceptset,
-                struct timeval *timeout);
+#include LWIP_INCLUDE_SOCKETS
 #endif
-#if LWIP_SOCKET_POLL
-int lwip_poll(struct pollfd *fds, nfds_t nfds, int timeout);
-#endif
-int lwip_ioctl(int s, long cmd, void *argp);
-int lwip_fcntl(int s, int cmd, int val);
-const char *lwip_inet_ntop(int af, const void *src, char *dst, socklen_t size);
-int lwip_inet_pton(int af, const char *src, void *dst);
-
-#if LWIP_COMPAT_SOCKETS
-#if LWIP_COMPAT_SOCKETS != 2
-/** @ingroup socket */
-#define accept(s,addr,addrlen)                    lwip_accept(s,addr,addrlen)
-/** @ingroup socket */
-#define bind(s,name,namelen)                      lwip_bind(s,name,namelen)
-/** @ingroup socket */
-#define shutdown(s,how)                           lwip_shutdown(s,how)
-/** @ingroup socket */
-#define getpeername(s,name,namelen)               lwip_getpeername(s,name,namelen)
-/** @ingroup socket */
-#define getsockname(s,name,namelen)               lwip_getsockname(s,name,namelen)
-/** @ingroup socket */
-#define setsockopt(s,level,optname,opval,optlen)  lwip_setsockopt(s,level,optname,opval,optlen)
-/** @ingroup socket */
-#define getsockopt(s,level,optname,opval,optlen)  lwip_getsockopt(s,level,optname,opval,optlen)
-/** @ingroup socket */
-#define closesocket(s)                            lwip_close(s)
-/** @ingroup socket */
-#define connect(s,name,namelen)                   lwip_connect(s,name,namelen)
-/** @ingroup socket */
-#define listen(s,backlog)                         lwip_listen(s,backlog)
-/** @ingroup socket */
-#define recv(s,mem,len,flags)                     lwip_recv(s,mem,len,flags)
-/** @ingroup socket */
-#define recvmsg(s,message,flags)                  lwip_recvmsg(s,message,flags)
-/** @ingroup socket */
-#define recvfrom(s,mem,len,flags,from,fromlen)    lwip_recvfrom(s,mem,len,flags,from,fromlen)
-/** @ingroup socket */
-#define send(s,dataptr,size,flags)                lwip_send(s,dataptr,size,flags)
-/** @ingroup socket */
-#define sendmsg(s,message,flags)                  lwip_sendmsg(s,message,flags)
-/** @ingroup socket */
-#define sendto(s,dataptr,size,flags,to,tolen)     lwip_sendto(s,dataptr,size,flags,to,tolen)
-/** @ingroup socket */
-#define socket(domain,type,protocol)              lwip_socket(domain,type,protocol)
-#if LWIP_SOCKET_SELECT
-/** @ingroup socket */
-#define select(maxfdp1,readset,writeset,exceptset,timeout)     lwip_select(maxfdp1,readset,writeset,exceptset,timeout)
-#endif
-#if LWIP_SOCKET_POLL
-/** @ingroup socket */
-#define poll(fds,nfds,timeout)                    lwip_poll(fds,nfds,timeout)
-#endif
-/** @ingroup socket */
-#define ioctlsocket(s,cmd,argp)                   lwip_ioctl(s,cmd,argp)
-/** @ingroup socket */
-#define inet_ntop(af,src,dst,size)                lwip_inet_ntop(af,src,dst,size)
-/** @ingroup socket */
-#define inet_pton(af,src,dst)                     lwip_inet_pton(af,src,dst)
-
-#if LWIP_POSIX_SOCKETS_IO_NAMES
-/** @ingroup socket */
-#define read(s,mem,len)                           lwip_read(s,mem,len)
-/** @ingroup socket */
-#define readv(s,iov,iovcnt)                       lwip_readv(s,iov,iovcnt)
-/** @ingroup socket */
-#define write(s,dataptr,len)                      lwip_write(s,dataptr,len)
-/** @ingroup socket */
-#define writev(s,iov,iovcnt)                      lwip_writev(s,iov,iovcnt)
-/** @ingroup socket */
-#define close(s)                                  lwip_close(s)
-/** @ingroup socket */
-#define fcntl(s,cmd,val)                          lwip_fcntl(s,cmd,val)
-/** @ingroup socket */
-#define ioctl(s,cmd,argp)                         lwip_ioctl(s,cmd,argp)
-#endif /* LWIP_POSIX_SOCKETS_IO_NAMES */
-#endif /* LWIP_COMPAT_SOCKETS != 2 */
-
-#endif /* LWIP_COMPAT_SOCKETS */
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* LWIP_SOCKET */
 
 #endif /* LWIP_HDR_SOCKETS_H */
-- 
2.11.0

