From 864326a46a2f19491d9bbc5e7256511874fbf9ee Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Joan=20Lled=C3=B3?= <jlledom@member.fsf.org>
Date: Tue, 23 May 2017 08:48:05 +0200
Subject: [PATCH] Sockets API: use OS's sys/socket.h instead of lwip/sock

---
 src/include/lwip/ip.h              |   6 ++
 src/include/lwip/lwip-sys-socket.h | 194 +++++++++++++++++++++++++++++++++++++
 src/include/lwip/sockets.h         | 138 +-------------------------
 3 files changed, 205 insertions(+), 133 deletions(-)
 create mode 100644 src/include/lwip/lwip-sys-socket.h

diff --git a/src/include/lwip/ip.h b/src/include/lwip/ip.h
index 3c89d5b..6f27ef8 100644
--- a/src/include/lwip/ip.h
+++ b/src/include/lwip/ip.h
@@ -96,9 +96,15 @@ struct ip_pcb {
 /*
  * Option flags per-socket. These are the same like SO_XXX in sockets.h
  */
+#ifndef LWIP_SYS_SOCKET
 #define SOF_REUSEADDR     0x04U  /* allow local address reuse */
 #define SOF_KEEPALIVE     0x08U  /* keep connections alive */
 #define SOF_BROADCAST     0x20U  /* permit to send and to receive broadcast messages (see IP_SOF_BROADCAST option) */
+#else
+#define SOF_REUSEADDR     SO_REUSEADDR  /* allow local address reuse */
+#define SOF_KEEPALIVE     SO_KEEPALIVE  /* keep connections alive */
+#define SOF_BROADCAST     SO_BROADCAST  /* permit to send and to receive broadcast messages (see IP_SOF_BROADCAST option) */
+#endif /* LWIP_SYS_SOCKET */
 
 /* These flags are inherited (e.g. from a listen-pcb to a connection-pcb): */
 #define SOF_INHERITED   (SOF_REUSEADDR|SOF_KEEPALIVE)
diff --git a/src/include/lwip/lwip-sys-socket.h b/src/include/lwip/lwip-sys-socket.h
new file mode 100644
index 0000000..1ebeecd
--- /dev/null
+++ b/src/include/lwip/lwip-sys-socket.h
@@ -0,0 +1,194 @@
+/**
+ * @file
+ * Posix declarations for <sys/socket.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_SYS_SOCKET_H
+#define LWIP_HDR_SYS_SOCKET_H
+
+#include "lwip/ip.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* 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 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
+
+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 !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;
+};
+
+/* 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))))
+
+/*
+ * Structure used for manipulating linger option.
+ */
+struct linger {
+  int l_onoff;                /* option on/off */
+  int l_linger;               /* linger time in seconds */
+};
+
+/* Socket protocol types (TCP/UDP/RAW) */
+#define SOCK_STREAM     1
+#define SOCK_DGRAM      2
+#define SOCK_RAW        3
+
+/*
+ * Level number for (get/set)sockopt() to apply to socket itself.
+ */
+#define  SOL_SOCKET  0xfff    /* options for socket level */
+
+/*
+ * Option flags per-socket. These must match the SOF_ flags in ip.h (checked in init.c)
+ */
+#define SO_REUSEADDR   SOF_REUSEADDR /* Allow local address reuse */
+#define SO_KEEPALIVE   SOF_KEEPALIVE /* keep connections alive */
+#define SO_BROADCAST   SOF_BROADCAST /* 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_LINGER       0x0080 /* linger on close if data present */
+#define SO_OOBINLINE    0x0100 /* Unimplemented: leave received OOB data in line */
+#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 */
+
+/* struct msghdr->msg_flags bit field values */
+#define MSG_TRUNC   0x04
+#define MSG_CTRUNC  0x08
+
+/* 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 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 */
+
+#ifndef SHUT_RD
+  #define SHUT_RD   0
+  #define SHUT_WR   1
+  #define SHUT_RDWR 2
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* LWIP_HDR_SYS_SOCKET_H */
diff --git a/src/include/lwip/sockets.h b/src/include/lwip/sockets.h
index 4f9913a..d8f8888 100644
--- a/src/include/lwip/sockets.h
+++ b/src/include/lwip/sockets.h
@@ -35,7 +35,6 @@
  *
  */
 
-
 #ifndef LWIP_HDR_SOCKETS_H
 #define LWIP_HDR_SOCKETS_H
 
@@ -49,15 +48,14 @@
 #include "lwip/inet.h"
 #include "lwip/errno.h"
 
+#ifndef LWIP_SYS_SOCKET
+#include "lwip/lwip-sys-socket.h"
+#endif /* LWIP_SYS_SOCKET */
+
 #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)
@@ -87,64 +85,12 @@ struct sockaddr_in6 {
 };
 #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
@@ -153,23 +99,6 @@ 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))
 
@@ -182,63 +111,16 @@ 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
@@ -255,14 +137,10 @@ struct linger {
 #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
  */
@@ -439,12 +317,6 @@ struct in_pktinfo {
 #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
-- 
2.1.4

