text: #ifndef __API_INC_SOCKET_H__
  #define __API_INC_SOCKET_H__
  
  #include "stdbool.h"
  #include "stdint.h"
  
  #ifdef __cplusplus
  extern "C" {
  #endif
  
  
  #ifndef __UINTPTR_T__
  typedef unsigned int        uintptr_t;
  #define __UINTPTR_T__
  #endif
  typedef uintptr_t mem_ptr_t;
  
  
  //////////////////////////def.h/////////////////////////
  
  /** Create u32_t value from bytes */
  #define LWIP_MAKEU32(a,b,c,d) (((u32_t)((a) & 0xff) << 24) | \
                                 ((u32_t)((b) & 0xff) << 16) | \
                                 ((u32_t)((c) & 0xff) << 8)  | \
                                  (u32_t)((d) & 0xff))
  
  
  
  /* These macros should be calculated by the preprocessor and are used
     with compile-time constants only (so that there is no little-endian
     overhead at runtime). */
  #define PP_HTONS(x) ((((x) & 0x00ffUL) << 8) | (((x) & 0xff00UL) >> 8))
  #define PP_NTOHS(x) PP_HTONS(x)
  #define PP_HTONL(x) ((((x) & 0x000000ffUL) << 24) | \
                       (((x) & 0x0000ff00UL) <<  8) | \
                       (((x) & 0x00ff0000UL) >>  8) | \
                       (((x) & 0xff000000UL) >> 24))
  #define PP_NTOHL(x) PP_HTONL(x)
  
  
  //////////////////////////////////////////////////////////////
  ///////////////////////////ip4_addr.h////////////////////////
  
  /** This is the aligned version of ip4_addr_t,
     used as local variable, on the stack, etc. */
  struct ip4_addr {
    u32_t addr;
  };
  
  /** ip4_addr_t uses a struct for convenience only, so that the same defines can
   * operate both on ip4_addr_t as well as on ip4_addr_p_t. */
  typedef struct ip4_addr ip4_addr_t;
  
  /* Forward declaration to not include netif.h */
  struct netif;
  
  /** 255.255.255.255 */
  #define IPADDR_NONE         ((u32_t)0xffffffffUL)
  /** 127.0.0.1 */
  #define IPADDR_LOOPBACK     ((u32_t)0x7f000001UL)
  /** 0.0.0.0 */
  #define IPADDR_ANY          ((u32_t)0x00000000UL)
  /** 255.255.255.255 */
  #define IPADDR_BROADCAST    ((u32_t)0xffffffffUL)
  
  /* Definitions of the bits in an Internet address integer.
  
     On subnets, host and network parts are found according to
     the subnet mask, not these masks.  */
  #define IP_CLASSA(a)        ((((u32_t)(a)) & 0x80000000UL) == 0)
  #define IP_CLASSA_NET       0xff000000
  #define IP_CLASSA_NSHIFT    24
  #define IP_CLASSA_HOST      (0xffffffff & ~IP_CLASSA_NET)
  #define IP_CLASSA_MAX       128
  
  #define IP_CLASSB(a)        ((((u32_t)(a)) & 0xc0000000UL) == 0x80000000UL)
  #define IP_CLASSB_NET       0xffff0000
  #define IP_CLASSB_NSHIFT    16
  #define IP_CLASSB_HOST      (0xffffffff & ~IP_CLASSB_NET)
  #define IP_CLASSB_MAX       65536
  
  #define IP_CLASSC(a)        ((((u32_t)(a)) & 0xe0000000UL) == 0xc0000000UL)
  #define IP_CLASSC_NET       0xffffff00
  #define IP_CLASSC_NSHIFT    8
  #define IP_CLASSC_HOST      (0xffffffff & ~IP_CLASSC_NET)
  
  #define IP_CLASSD(a)        (((u32_t)(a) & 0xf0000000UL) == 0xe0000000UL)
  #define IP_CLASSD_NET       0xf0000000          /* These ones aren't really */
  #define IP_CLASSD_NSHIFT    28                  /*   net and host fields, but */
  #define IP_CLASSD_HOST      0x0fffffff          /*   routing needn't know. */
  #define IP_MULTICAST(a)     IP_CLASSD(a)
  
  #define IP_EXPERIMENTAL(a)  (((u32_t)(a) & 0xf0000000UL) == 0xf0000000UL)
  #define IP_BADCLASS(a)      (((u32_t)(a) & 0xf0000000UL) == 0xf0000000UL)
  
  #define IP_LOOPBACKNET      127                 /* official! */
  
  /** Set an IP address given by the four byte-parts */
  #define IP4_ADDR(ipaddr, a,b,c,d)  (ipaddr)->addr = PP_HTONL(LWIP_MAKEU32(a,b,c,d))
  
  /** Copy IP address - faster than ip4_addr_set: no NULL check */
  #define ip4_addr_copy(dest, src) ((dest).addr = (src).addr)
  /** Safely copy one IP address to another (src may be NULL) */
  #define ip4_addr_set(dest, src) ((dest)->addr = \
                                      ((src) == NULL ? 0 : \
                                      (src)->addr))
  /** Set complete address to zero */
  #define ip4_addr_set_zero(ipaddr)     ((ipaddr)->addr = 0)
  /** Set address to IPADDR_ANY (no need for lwip_htonl()) */
  #define ip4_addr_set_any(ipaddr)      ((ipaddr)->addr = IPADDR_ANY)
  /** Set address to loopback address */
  #define ip4_addr_set_loopback(ipaddr) ((ipaddr)->addr = PP_HTONL(IPADDR_LOOPBACK))
  /** Check if an address is in the loopback region */
  #define ip4_addr_isloopback(ipaddr)    (((ipaddr)->addr & PP_HTONL(IP_CLASSA_NET)) == PP_HTONL(((u32_t)IP_LOOPBACKNET) << 24))
  /** Safely copy one IP address to another and change byte order
   * from host- to network-order. */
  /*#define ip4_addr_set_hton(dest, src) ((dest)->addr = \
                                 ((src) == NULL ? 0:\
                                 lwip_htonl((src)->addr)))
  */
  /** IPv4 only: set the IP address given as an u32_t */
  #define ip4_addr_set_u32(dest_ipaddr, src_u32) ((dest_ipaddr)->addr = (src_u32))
  /** IPv4 only: get the IP address as an u32_t */
  #define ip4_addr_get_u32(src_ipaddr) ((src_ipaddr)->addr)
  
  /** Get the network address by combining host address with netmask */
  #define ip4_addr_get_network(target, host, netmask) do { ((target)->addr = ((host)->addr) & ((netmask)->addr)); } while(0)
  
  /**
   * Determine if two address are on the same network.
   *
   * @arg addr1 IP address 1
   * @arg addr2 IP address 2
   * @arg mask network identifier mask
   * @return !0 if the network identifiers of both address match
   */
  #define ip4_addr_netcmp(addr1, addr2, mask) (((addr1)->addr & \
                                                (mask)->addr) == \
                                               ((addr2)->addr & \
                                                (mask)->addr))
  #define ip4_addr_cmp(addr1, addr2) ((addr1)->addr == (addr2)->addr)
  
  #define ip4_addr_isany_val(addr1)   ((addr1).addr == IPADDR_ANY)
  #define ip4_addr_isany(addr1) ((addr1) == NULL || ip4_addr_isany_val(*(addr1)))
  
  #define ip4_addr_isbroadcast(addr1, netif) ip4_addr_isbroadcast_u32((addr1)->addr, netif)
  u8_t ip4_addr_isbroadcast_u32(u32_t addr, const struct netif *netif);
  
  #define ip_addr_netmask_valid(netmask) ip4_addr_netmask_valid((netmask)->addr)
  u8_t ip4_addr_netmask_valid(u32_t netmask);
  
  #define ip4_addr_ismulticast(addr1) (((addr1)->addr & PP_HTONL(0xf0000000UL)) == PP_HTONL(0xe0000000UL))
  
  #define ip4_addr_islinklocal(addr1) (((addr1)->addr & PP_HTONL(0xffff0000UL)) == PP_HTONL(0xa9fe0000UL))
  
  /* Get one byte from the 4-byte address */
  #define ip4_addr1(ipaddr) (((const u8_t*)(&(ipaddr)->addr))[0])
  #define ip4_addr2(ipaddr) (((const u8_t*)(&(ipaddr)->addr))[1])
  #define ip4_addr3(ipaddr) (((const u8_t*)(&(ipaddr)->addr))[2])
  #define ip4_addr4(ipaddr) (((const u8_t*)(&(ipaddr)->addr))[3])
  /* These are cast to u16_t, with the intent that they are often arguments
   * to printf using the U16_F format from cc.h. */
  #define ip4_addr1_16(ipaddr) ((u16_t)ip4_addr1(ipaddr))
  #define ip4_addr2_16(ipaddr) ((u16_t)ip4_addr2(ipaddr))
  #define ip4_addr3_16(ipaddr) ((u16_t)ip4_addr3(ipaddr))
  #define ip4_addr4_16(ipaddr) ((u16_t)ip4_addr4(ipaddr))
  
  #define IP4ADDR_STRLEN_MAX  16
  
  
  //////////////////////ip6_addr.h///////////////////
  #define LWIP_IPV6_SCOPES 0
  /** This is the aligned version of ip6_addr_t,
      used as local variable, on the stack, etc. */
  struct ip6_addr {
    u32_t addr[4];
  #if LWIP_IPV6_SCOPES //0
    u8_t zone;
  #endif /* LWIP_IPV6_SCOPES */
  };
  
  /** IPv6 address */
  typedef struct ip6_addr ip6_addr_t;
  
  /** Set an IPv6 partial address given by byte-parts */
  #define IP6_ADDR_PART(ip6addr, index, a,b,c,d) \
    (ip6addr)->addr[index] = PP_HTONL(LWIP_MAKEU32(a,b,c,d))
  
  
  
  ///////////////////////inet.h//////////////////////////
  
  /* 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
  #ifndef INET6_ADDRSTRLEN
  #define INET6_ADDRSTRLEN    IP6ADDR_STRLEN_MAX
  #endif
  
  #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))
  
  
  /*#################      socket      #################################*/
  #define MAX_SOCKET_NUM 20
  #define MAX_DNS_DOMAIN_LENGTH
  
  typedef enum{
      TCP = 0,
      UDP =1
  }TCP_UDP_t;
  
  typedef enum{
      DNS_STATUS_ERROR = -1,
      DNS_STATUS_OK    =  0,
      DNS_STATUS_WAIT  =  1,
      DNS_STATUS_MAX
  }DNS_Status_t;
  
  
  typedef enum{
      /** No error, everything OK. */
      API_SOCKET_ERROR_NONE = 0,
      /** Out of memory error.     */
      API_SOCKET_ERROR_MEM        = -1,
      /** Buffer error.            */
      API_SOCKET_ERROR_BUF        = -2,
      /** Timeout.                 */
      API_SOCKET_ERROR_TIMEOUT    = -3,
      /** Routing problem.         */
      API_SOCKET_ERROR_RTE        = -4,
      /** Operation in progress    */
      API_SOCKET_ERROR_INPROGRESS = -5,
      /** Illegal value.           */
      API_SOCKET_ERROR_VAL        = -6,
      /** Operation would block.   */
      API_SOCKET_ERROR_WOULDBLOCK = -7,
      /** Address in use.          */
      API_SOCKET_ERROR_USE        = -8,
      /** Already connecting.      */
      API_SOCKET_ERROR_ALREADY    = -9,
      /** Conn already established.*/
      API_SOCKET_ERROR_ISCONN     = -10,
      /** Not connected.           */
      API_SOCKET_ERROR_CONN       = -11,
      /** Low-level netif error    */
      API_SOCKET_ERROR_IF         = -12,
  
      /** Connection aborted.      */
      API_SOCKET_ERROR_ABRT       = -13,
      /** Connection reset.        */
      API_SOCKET_ERROR_RST        = -14,
      /** Connection closed.       */
      API_SOCKET_ERROR_CLSD       = -15,
      /** Illegal argument.        */
      API_SOCKET_ERROR_ARG        = -16
  }API_Socket_Error_t;
  
  typedef s8_t err_t;
  
  /** Definitions for error constants. */
  typedef enum {
  /** No error, everything OK. */
    ERR_OK         = 0,
  /** Out of memory error.     */
    ERR_MEM        = -1,
  /** Buffer error.            */
    ERR_BUF        = -2,
  /** Timeout.                 */
    ERR_TIMEOUT    = -3,
  /** Routing problem.         */
    ERR_RTE        = -4,
  /** Operation in progress    */
    ERR_INPROGRESS = -5,
  /** Illegal value.           */
    ERR_VAL        = -6,
  /** Operation would block.   */
    ERR_WOULDBLOCK = -7,
  /** Address in use.          */
    ERR_USE        = -8,
  /** Already connecting.      */
    ERR_ALREADY    = -9,
  /** Conn already established.*/
    ERR_ISCONN     = -10,
  /** Not connected.           */
    ERR_CONN       = -11,
  /** Low-level netif error    */
    ERR_IF         = -12,
  
  /** Connection aborted.      */
    ERR_ABRT       = -13,
  /** Connection reset.        */
    ERR_RST        = -14,
  /** Connection closed.       */
    ERR_CLSD       = -15,
  /** Illegal argument.        */
    ERR_ARG        = -16
  } err_enum_t;
  
  /* 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
  
  /* 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];
  };
  
  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 */
  };
  
  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 IPV6
    u32_t       s2_data3[3];
  // #endif /* 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"
  #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 NETIF_NAMESIZE 6
  #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
  #define AF_INET6        10
  #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
  #define IPPROTO_IPV6    41
  #define IPPROTO_ICMPV6  58
  #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
  
  /*
   * 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 */
  
  /*
   * 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. */
  
  /*
   * Options and types for UDP multicast traffic handling
   */
  #define IP_MULTICAST_TTL   5
  #define IP_MULTICAST_IF    6
  #define IP_MULTICAST_LOOP  7
  
  /*
   * 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;
  
  struct in_pktinfo {
    unsigned int   ipi_ifindex;  /* Interface index */
    struct in_addr ipi_spec_dst;
    struct in_addr ipi_addr;     /* Destination (from header) address */
  };
  
  /*
   * 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)        (IOC_VOID|((x)<<8)|(y))
  
  #define _IOR(x,y,t)     (IOC_OUT|(((long)sizeof(t)&IOCPARM_MASK)<<16)|((x)<<8)|(y))
  
  #define _IOW(x,y,t)     (IOC_IN|(((long)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    1 /* 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 */
  #if !defined MEMP_NUM_NETCONN
  #define MEMP_NUM_NETCONN                8
  #endif
  
  #if !defined LWIP_SOCKET_OFFSET
  #define LWIP_SOCKET_OFFSET              1
  #endif
  
  #ifndef FD_SET
  #undef  FD_SETSIZE
  /* Make FD_SETSIZE match NUM_SOCKETS in socket.c */
  #define FD_SETSIZE    MEMP_NUM_NETCONN
  #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] |=  (1 << (((n)-LWIP_SOCKET_OFFSET) & 7)))
  #define FD_CLR(n, p)  FDSETSAFESET(n, (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 LWIP_SOCKET_OFFSET
  #error LWIP_SOCKET_OFFSET does not work with external FD_SET!
  #elif FD_SETSIZE < MEMP_NUM_NETCONN
  #error "external FD_SETSIZE too small for number of sockets"
  #endif /* FD_SET */
  
  
  
  
  
  typedef void (*DNS_CALLBACK_FUNC_T)(DNS_Status_t status, void* param);
  
  
  #ifdef __cplusplus
  }
  #endif
  
  #endif
  