56 #if LWIP_CHECKSUM_ON_COPY 66 #define LWIP_NETCONN 1 71 #define LWIP_NETCONN 0 75 #define IP4ADDR_PORT_TO_SOCKADDR(sin, ipaddr, port) do { \ 76 (sin)->sin_len = sizeof(struct sockaddr_in); \ 77 (sin)->sin_family = AF_INET; \ 78 (sin)->sin_port = htons((port)); \ 79 inet_addr_from_ipaddr(&(sin)->sin_addr, ipaddr); \ 80 memset((sin)->sin_zero, 0, SIN_ZERO_LEN); }while(0) 81 #define SOCKADDR4_TO_IP4ADDR_PORT(sin, ipaddr, port) do { \ 82 inet_addr_to_ipaddr(ip_2_ip4(ipaddr), &((sin)->sin_addr)); \ 83 (port) = ntohs((sin)->sin_port); }while(0) 87 #define IP6ADDR_PORT_TO_SOCKADDR(sin6, ipaddr, port) do { \ 88 (sin6)->sin6_len = sizeof(struct sockaddr_in6); \ 89 (sin6)->sin6_family = AF_INET6; \ 90 (sin6)->sin6_port = htons((port)); \ 91 (sin6)->sin6_flowinfo = 0; \ 92 inet6_addr_from_ip6addr(&(sin6)->sin6_addr, ipaddr); \ 93 (sin6)->sin6_scope_id = 0; }while(0) 94 #define SOCKADDR6_TO_IP6ADDR_PORT(sin6, ipaddr, port) do { \ 95 inet6_addr_to_ip6addr(ip_2_ip6(ipaddr), &((sin6)->sin6_addr)); \ 96 (port) = ntohs((sin6)->sin6_port); }while(0) 99 #if LWIP_IPV4 && LWIP_IPV6 100 static void sockaddr_to_ipaddr_port(
const struct sockaddr* sockaddr,
ip_addr_t* ipaddr,
u16_t* port);
102 #define IS_SOCK_ADDR_LEN_VALID(namelen) (((namelen) == sizeof(struct sockaddr_in)) || \ 103 ((namelen) == sizeof(struct sockaddr_in6))) 104 #define IS_SOCK_ADDR_TYPE_VALID(name) (((name)->sa_family == AF_INET) || \ 105 ((name)->sa_family == AF_INET6)) 106 #define SOCK_ADDR_TYPE_MATCH(name, sock) \ 107 ((((name)->sa_family == AF_INET) && !(NETCONNTYPE_ISIPV6((sock)->conn->type))) || \ 108 (((name)->sa_family == AF_INET6) && (NETCONNTYPE_ISIPV6((sock)->conn->type)))) 109 #define IPADDR_PORT_TO_SOCKADDR(sockaddr, ipaddr, port) do { \ 110 if (IP_IS_V6(ipaddr)) { \ 111 IP6ADDR_PORT_TO_SOCKADDR((struct sockaddr_in6*)(void*)(sockaddr), ip_2_ip6(ipaddr), port); \ 113 IP4ADDR_PORT_TO_SOCKADDR((struct sockaddr_in*)(void*)(sockaddr), ip_2_ip4(ipaddr), port); \ 115 #define SOCKADDR_TO_IPADDR_PORT(sockaddr, ipaddr, port) sockaddr_to_ipaddr_port(sockaddr, ipaddr, &(port)) 116 #define DOMAIN_TO_NETCONN_TYPE(domain, type) (((domain) == AF_INET) ? \ 117 (type) : (enum netconn_type)((type) | NETCONN_TYPE_IPV6)) 119 #define IS_SOCK_ADDR_LEN_VALID(namelen) ((namelen) == sizeof(struct sockaddr_in6)) 120 #define IS_SOCK_ADDR_TYPE_VALID(name) ((name)->sa_family == AF_INET6) 121 #define SOCK_ADDR_TYPE_MATCH(name, sock) 1 122 #define IPADDR_PORT_TO_SOCKADDR(sockaddr, ipaddr, port) \ 123 IP6ADDR_PORT_TO_SOCKADDR((struct sockaddr_in6*)(void*)(sockaddr), ip_2_ip6(ipaddr), port) 124 #define SOCKADDR_TO_IPADDR_PORT(sockaddr, ipaddr, port) \ 125 SOCKADDR6_TO_IP6ADDR_PORT((const struct sockaddr_in6*)(const void*)(sockaddr), ipaddr, port) 126 #define DOMAIN_TO_NETCONN_TYPE(domain, netconn_type) (netconn_type) 128 #define IS_SOCK_ADDR_LEN_VALID(namelen) ((namelen) == sizeof(struct sockaddr_in)) 129 #define IS_SOCK_ADDR_TYPE_VALID(name) ((name)->sa_family == AF_INET) 130 #define SOCK_ADDR_TYPE_MATCH(name, sock) 1 131 #define IPADDR_PORT_TO_SOCKADDR(sockaddr, ipaddr, port) \ 132 IP4ADDR_PORT_TO_SOCKADDR((struct sockaddr_in*)(void*)(sockaddr), ip_2_ip4(ipaddr), port) 133 #define SOCKADDR_TO_IPADDR_PORT(sockaddr, ipaddr, port) \ 134 SOCKADDR4_TO_IP4ADDR_PORT((const struct sockaddr_in*)(const void*)(sockaddr), ipaddr, port) 135 #define DOMAIN_TO_NETCONN_TYPE(domain, netconn_type) (netconn_type) 138 #define IS_SOCK_ADDR_TYPE_VALID_OR_UNSPEC(name) (((name)->sa_family == AF_UNSPEC) || \ 139 IS_SOCK_ADDR_TYPE_VALID(name)) 140 #define SOCK_ADDR_TYPE_MATCH_OR_UNSPEC(name, sock) (((name)->sa_family == AF_UNSPEC) || \ 141 SOCK_ADDR_TYPE_MATCH(name, sock)) 142 #define IS_SOCK_ADDR_ALIGNED(name) ((((mem_ptr_t)(name)) % 4) == 0) 145 #define LWIP_SOCKOPT_CHECK_OPTLEN(optlen, opttype) do { if ((optlen) < sizeof(opttype)) { return EINVAL; }}while(0) 146 #define LWIP_SOCKOPT_CHECK_OPTLEN_CONN(sock, optlen, opttype) do { \ 147 LWIP_SOCKOPT_CHECK_OPTLEN(optlen, opttype); \ 148 if ((sock)->conn == NULL) { return EINVAL; } }while(0) 149 #define LWIP_SOCKOPT_CHECK_OPTLEN_CONN_PCB(sock, optlen, opttype) do { \ 150 LWIP_SOCKOPT_CHECK_OPTLEN(optlen, opttype); \ 151 if (((sock)->conn == NULL) || ((sock)->conn->pcb.tcp == NULL)) { return EINVAL; } }while(0) 152 #define LWIP_SOCKOPT_CHECK_OPTLEN_CONN_PCB_TYPE(sock, optlen, opttype, netconntype) do { \ 153 LWIP_SOCKOPT_CHECK_OPTLEN_CONN_PCB(sock, optlen, opttype); \ 154 if (NETCONNTYPE_GROUP(netconn_type((sock)->conn)) != netconntype) { return ENOPROTOOPT; } }while(0) 157 #define LWIP_SETGETSOCKOPT_DATA_VAR_REF(name) API_VAR_REF(name) 158 #define LWIP_SETGETSOCKOPT_DATA_VAR_DECLARE(name) API_VAR_DECLARE(struct lwip_setgetsockopt_data, name) 159 #define LWIP_SETGETSOCKOPT_DATA_VAR_FREE(name) API_VAR_FREE(MEMP_SOCKET_SETGETSOCKOPT_DATA, name) 160 #if LWIP_MPU_COMPATIBLE 161 #define LWIP_SETGETSOCKOPT_DATA_VAR_ALLOC(name, sock) do { \ 162 name = (struct lwip_setgetsockopt_data *)memp_malloc(MEMP_SOCKET_SETGETSOCKOPT_DATA); \ 163 if (name == NULL) { \ 164 sock_set_errno(sock, ENOMEM); \ 168 #define LWIP_SETGETSOCKOPT_DATA_VAR_ALLOC(name, sock) 171 #if LWIP_SO_SNDRCVTIMEO_NONSTANDARD 172 #define LWIP_SO_SNDRCVTIMEO_OPTTYPE int 173 #define LWIP_SO_SNDRCVTIMEO_SET(optval, val) (*(int *)(optval) = (val)) 174 #define LWIP_SO_SNDRCVTIMEO_GET_MS(optval) ((s32_t)*(const int*)(optval)) 176 #define LWIP_SO_SNDRCVTIMEO_OPTTYPE struct timeval 177 #define LWIP_SO_SNDRCVTIMEO_SET(optval, val) do { \ 179 ((struct timeval *)(optval))->tv_sec = (loc) / 1000U; \ 180 ((struct timeval *)(optval))->tv_usec = ((loc) % 1000U) * 1000U; }while(0) 181 #define LWIP_SO_SNDRCVTIMEO_GET_MS(optval) ((((const struct timeval *)(optval))->tv_sec * 1000U) + (((const struct timeval *)(optval))->tv_usec / 1000U)) 184 #define NUM_SOCKETS MEMP_NUM_NETCONN 190 #define SELWAIT_T u8_t 196 struct netconn *conn;
212 SELWAIT_T select_waiting;
215 #if LWIP_NETCONN_SEM_PER_THREAD 216 #define SELECT_SEM_T sys_sem_t* 217 #define SELECT_SEM_PTR(sem) (sem) 219 #define SELECT_SEM_T sys_sem_t 220 #define SELECT_SEM_PTR(sem) (&(sem)) 224 struct lwip_select_cb {
226 struct lwip_select_cb *next;
228 struct lwip_select_cb *prev;
244 union sockaddr_aligned {
247 struct sockaddr_in6 sin6;
250 struct sockaddr_in sin;
256 #ifndef LWIP_SOCKET_MAX_MEMBERSHIPS 257 #define LWIP_SOCKET_MAX_MEMBERSHIPS NUM_SOCKETS 262 struct lwip_socket_multicast_pair {
268 ip4_addr_t multi_addr;
271 struct lwip_socket_multicast_pair socket_ipv4_multicast_memberships[LWIP_SOCKET_MAX_MEMBERSHIPS];
273 static int lwip_socket_register_membership(
int s,
const ip4_addr_t *if_addr,
const ip4_addr_t *multi_addr);
274 static void lwip_socket_unregister_membership(
int s,
const ip4_addr_t *if_addr,
const ip4_addr_t *multi_addr);
275 static void lwip_socket_drop_registered_memberships(
int s);
279 static struct lwip_sock sockets[NUM_SOCKETS];
281 static struct lwip_select_cb *select_cb_list;
284 static volatile int select_cb_ctr;
288 static const int err_to_errno_table[] = {
308 #define ERR_TO_ERRNO_TABLE_SIZE LWIP_ARRAYSIZE(err_to_errno_table) 310 #define err_to_errno(err) \ 311 ((unsigned)(-(err)) < ERR_TO_ERRNO_TABLE_SIZE ? \ 312 err_to_errno_table[-(err)] : EIO) 314 #if LWIP_SOCKET_SET_ERRNO 316 #define set_errno(err) do { if (err) { errno = (err); } } while(0) 319 #define set_errno(err) 322 #define sock_set_errno(sk, e) do { \ 323 const int sockerr = (e); \ 324 sk->err = (u8_t)sockerr; \ 325 set_errno(sockerr); \ 329 static void event_callback(
struct netconn *conn,
enum netconn_evt evt,
u16_t len);
330 #if !LWIP_TCPIP_CORE_LOCKING 331 static void lwip_getsockopt_callback(
void *arg);
332 static void lwip_setsockopt_callback(
void *arg);
334 static u8_t lwip_getsockopt_impl(
int s,
int level,
int optname,
void *optval, socklen_t *optlen);
335 static u8_t lwip_setsockopt_impl(
int s,
int level,
int optname,
const void *optval, socklen_t optlen);
337 #if LWIP_IPV4 && LWIP_IPV6 339 sockaddr_to_ipaddr_port(
const struct sockaddr* sockaddr,
ip_addr_t* ipaddr,
u16_t* port)
341 if ((sockaddr->sa_family) == AF_INET6) {
342 SOCKADDR6_TO_IP6ADDR_PORT((
const struct sockaddr_in6*)(
const void*)(sockaddr), ipaddr, *port);
343 ipaddr->type = IPADDR_TYPE_V6;
345 SOCKADDR4_TO_IP4ADDR_PORT((
const struct sockaddr_in*)(
const void*)(sockaddr), ipaddr, *port);
346 ipaddr->type = IPADDR_TYPE_V4;
353 lwip_socket_thread_init(
void)
355 netconn_thread_init();
360 lwip_socket_thread_cleanup(
void)
362 netconn_thread_cleanup();
371 static struct lwip_sock *
374 struct lwip_sock *sock;
378 if ((s < 0) || (s >= NUM_SOCKETS)) {
401 static struct lwip_sock *
405 if ((s < 0) || (s >= NUM_SOCKETS)) {
408 if (!sockets[s].conn) {
423 alloc_socket(
struct netconn *newconn,
int accepted)
429 for (i = 0; i < NUM_SOCKETS; ++i) {
432 if (!sockets[i].conn) {
433 sockets[i].conn = newconn;
437 sockets[i].lastdata =
NULL;
438 sockets[i].lastoffset = 0;
439 sockets[i].rcvevent = 0;
442 sockets[i].sendevent = (NETCONNTYPE_GROUP(newconn->type) == NETCONN_TCP ? (accepted != 0) : 1);
443 sockets[i].errevent = 0;
445 sockets[i].select_waiting = 0;
460 free_socket(
struct lwip_sock *sock,
int is_tcp)
464 lastdata = sock->lastdata;
465 sock->lastdata =
NULL;
466 sock->lastoffset = 0;
473 if (lastdata !=
NULL) {
477 netbuf_delete((
struct netbuf *)lastdata);
489 lwip_accept(
int s,
struct sockaddr *addr, socklen_t *addrlen)
491 struct lwip_sock *sock, *nsock;
492 struct netconn *newconn;
500 sock = get_socket(s);
505 if (netconn_is_nonblocking(sock->conn) && (sock->rcvevent <= 0)) {
507 sock_set_errno(sock, EWOULDBLOCK);
512 err = netconn_accept(sock->conn, &newconn);
515 if (NETCONNTYPE_GROUP(netconn_type(sock->conn)) != NETCONN_TCP) {
516 sock_set_errno(sock, EOPNOTSUPP);
519 sock_set_errno(sock, err_to_errno(err));
524 netconn_set_noautorecved(newconn, 1);
526 newsock = alloc_socket(newconn, 1);
528 netconn_delete(newconn);
529 sock_set_errno(sock, ENFILE);
533 LWIP_ASSERT(
"newconn->callback == event_callback", newconn->callback == event_callback);
542 nsock->rcvevent += (
s16_t)(-1 - newconn->socket);
543 newconn->socket = newsock;
550 union sockaddr_aligned tempaddr;
552 err = netconn_peer(newconn, &naddr, &port);
555 netconn_delete(newconn);
556 free_socket(nsock, 1);
557 sock_set_errno(sock, err_to_errno(err));
562 IPADDR_PORT_TO_SOCKADDR(&tempaddr, &naddr, port);
563 if (*addrlen > tempaddr.sa.sa_len) {
564 *addrlen = tempaddr.sa.sa_len;
566 MEMCPY(addr, &tempaddr, *addrlen);
575 sock_set_errno(sock, 0);
580 lwip_bind(
int s,
const struct sockaddr *name, socklen_t namelen)
582 struct lwip_sock *sock;
587 sock = get_socket(s);
592 if (!SOCK_ADDR_TYPE_MATCH(name, sock)) {
594 sock_set_errno(sock, err_to_errno(
ERR_VAL));
599 LWIP_ERROR(
"lwip_bind: invalid address", (IS_SOCK_ADDR_LEN_VALID(namelen) &&
600 IS_SOCK_ADDR_TYPE_VALID(name) && IS_SOCK_ADDR_ALIGNED(name)),
601 sock_set_errno(sock, err_to_errno(
ERR_ARG));
return -1;);
604 SOCKADDR_TO_IPADDR_PORT(name, &local_addr, local_port);
609 err = netconn_bind(sock->conn, &local_addr, local_port);
613 sock_set_errno(sock, err_to_errno(err));
618 sock_set_errno(sock, 0);
625 struct lwip_sock *sock;
631 sock = get_socket(s);
636 if (sock->conn !=
NULL) {
637 is_tcp = NETCONNTYPE_GROUP(netconn_type(sock->conn)) == NETCONN_TCP;
644 lwip_socket_drop_registered_memberships(s);
647 err = netconn_delete(sock->conn);
649 sock_set_errno(sock, err_to_errno(err));
653 free_socket(sock, is_tcp);
659 lwip_connect(
int s,
const struct sockaddr *name, socklen_t namelen)
661 struct lwip_sock *sock;
664 sock = get_socket(s);
669 if (!SOCK_ADDR_TYPE_MATCH_OR_UNSPEC(name, sock)) {
671 sock_set_errno(sock, err_to_errno(
ERR_VAL));
676 if (name->sa_family == AF_UNSPEC) {
678 err = netconn_disconnect(sock->conn);
684 LWIP_ERROR(
"lwip_connect: invalid address", IS_SOCK_ADDR_LEN_VALID(namelen) &&
685 IS_SOCK_ADDR_TYPE_VALID_OR_UNSPEC(name) && IS_SOCK_ADDR_ALIGNED(name),
686 sock_set_errno(sock, err_to_errno(
ERR_ARG));
return -1;);
688 SOCKADDR_TO_IPADDR_PORT(name, &remote_addr, remote_port);
693 err = netconn_connect(sock->conn, &remote_addr, remote_port);
698 sock_set_errno(sock, err_to_errno(err));
703 sock_set_errno(sock, 0);
716 lwip_listen(
int s,
int backlog)
718 struct lwip_sock *sock;
723 sock = get_socket(s);
731 err = netconn_listen_with_backlog(sock->conn, (
u8_t)backlog);
735 if (NETCONNTYPE_GROUP(netconn_type(sock->conn)) != NETCONN_TCP) {
736 sock_set_errno(sock, EOPNOTSUPP);
739 sock_set_errno(sock, err_to_errno(err));
743 sock_set_errno(sock, 0);
748 lwip_recvfrom(
int s,
void *
mem,
size_t len,
int flags,
749 struct sockaddr *from, socklen_t *fromlen)
751 struct lwip_sock *sock;
754 u16_t buflen, copylen;
760 sock = get_socket(s);
768 if (sock->lastdata) {
769 buf = sock->lastdata;
772 if (((flags & MSG_DONTWAIT) || netconn_is_nonblocking(sock->conn)) &&
773 (sock->rcvevent <= 0)) {
776 netconn_recved(sock->conn, (
u32_t)off);
778 sock_set_errno(sock, 0);
782 sock_set_errno(sock, EWOULDBLOCK);
788 if (NETCONNTYPE_GROUP(netconn_type(sock->conn)) == NETCONN_TCP) {
789 err = netconn_recv_tcp_pbuf(sock->conn, (
struct pbuf **)&buf);
791 err = netconn_recv(sock->conn, (
struct netbuf **)&buf);
799 netconn_recved(sock->conn, (
u32_t)off);
802 event_callback(sock->conn, NETCONN_EVT_RCVPLUS, 0);
805 sock_set_errno(sock, 0);
811 sock_set_errno(sock, err_to_errno(err));
819 sock->lastdata = buf;
822 if (NETCONNTYPE_GROUP(netconn_type(sock->conn)) == NETCONN_TCP) {
823 p = (
struct pbuf *)buf;
825 p = ((
struct netbuf *)buf)->p;
829 buflen, len, off, sock->lastoffset));
831 buflen -= sock->lastoffset;
836 copylen = (
u16_t)len;
845 if (NETCONNTYPE_GROUP(netconn_type(sock->conn)) == NETCONN_TCP) {
846 LWIP_ASSERT(
"invalid copylen, len would underflow", len >= copylen);
850 (sock->rcvevent <= 0) ||
851 ((flags & MSG_PEEK) != 0)) {
867 union sockaddr_aligned saddr;
869 if (NETCONNTYPE_GROUP(netconn_type(sock->conn)) == NETCONN_TCP) {
871 netconn_getaddr(sock->conn, fromaddr, &port, 0);
873 port = netbuf_fromport((
struct netbuf *)buf);
874 fromaddr = netbuf_fromaddr((
struct netbuf *)buf);
876 IPADDR_PORT_TO_SOCKADDR(&saddr, fromaddr, port);
883 if (*fromlen > saddr.sa.sa_len) {
884 *fromlen = saddr.sa.sa_len;
886 MEMCPY(from, &saddr, *fromlen);
892 if ((flags & MSG_PEEK) == 0) {
896 if ((NETCONNTYPE_GROUP(netconn_type(sock->conn)) == NETCONN_TCP) && (buflen - copylen > 0)) {
897 sock->lastdata = buf;
898 sock->lastoffset += copylen;
901 sock->lastdata =
NULL;
902 sock->lastoffset = 0;
904 if (NETCONNTYPE_GROUP(netconn_type(sock->conn)) == NETCONN_TCP) {
907 netbuf_delete((
struct netbuf *)buf);
914 if ((off > 0) && (NETCONNTYPE_GROUP(netconn_type(sock->conn)) == NETCONN_TCP) &&
915 ((flags & MSG_PEEK) == 0)) {
917 netconn_recved(sock->conn, (
u32_t)off);
919 sock_set_errno(sock, 0);
924 lwip_read(
int s,
void *mem,
size_t len)
926 return lwip_recvfrom(s, mem, len, 0,
NULL,
NULL);
930 lwip_recv(
int s,
void *mem,
size_t len,
int flags)
932 return lwip_recvfrom(s, mem, len, flags,
NULL,
NULL);
936 lwip_send(
int s,
const void *data,
size_t size,
int flags)
938 struct lwip_sock *sock;
944 s, data, size, flags));
946 sock = get_socket(s);
951 if (NETCONNTYPE_GROUP(netconn_type(sock->conn)) != NETCONN_TCP) {
952 #if (LWIP_UDP || LWIP_RAW) 953 return lwip_sendto(s, data, size, flags,
NULL, 0);
955 sock_set_errno(sock, err_to_errno(
ERR_ARG));
960 write_flags = NETCONN_COPY |
961 ((flags & MSG_MORE) ? NETCONN_MORE : 0) |
962 ((flags & MSG_DONTWAIT) ? NETCONN_DONTBLOCK : 0);
964 err = netconn_write_partly(sock->conn, data, size, write_flags, &written);
967 sock_set_errno(sock, err_to_errno(err));
968 return (err ==
ERR_OK ? (
int)written : -1);
972 lwip_sendmsg(
int s,
const struct msghdr *msg,
int flags)
974 struct lwip_sock *sock;
975 struct netbuf *chain_buf;
985 sock = get_socket(s);
991 sock_set_errno(sock, err_to_errno(
ERR_ARG));
return -1;);
996 LWIP_ERROR(
"lwip_sendmsg: invalid msghdr iov", (msg->msg_iov !=
NULL && msg->msg_iovlen != 0),
997 sock_set_errno(sock, err_to_errno(
ERR_ARG));
return -1;);
999 if (NETCONNTYPE_GROUP(netconn_type(sock->conn)) == NETCONN_TCP) {
1001 write_flags = NETCONN_COPY |
1002 ((flags & MSG_MORE) ? NETCONN_MORE : 0) |
1003 ((flags & MSG_DONTWAIT) ? NETCONN_DONTBLOCK : 0);
1005 for (i = 0; i < msg->msg_iovlen; i++) {
1007 err = netconn_write_partly(sock->conn, msg->msg_iov[i].iov_base, msg->msg_iov[i].iov_len, write_flags, &written);
1011 if (written != msg->msg_iov[i].iov_len)
1024 sock_set_errno(sock, err_to_errno(err));
1027 sock_set_errno(sock, err_to_errno(
ERR_ARG));
1032 #if LWIP_UDP || LWIP_RAW 1035 LWIP_ERROR(
"lwip_sendmsg: invalid msghdr name", (((msg->msg_name ==
NULL) && (msg->msg_namelen == 0)) ||
1036 IS_SOCK_ADDR_LEN_VALID(msg->msg_namelen)) ,
1037 sock_set_errno(sock, err_to_errno(
ERR_ARG));
return -1;);
1040 chain_buf = netbuf_new();
1042 sock_set_errno(sock, err_to_errno(
ERR_MEM));
1045 if (msg->msg_name) {
1046 SOCKADDR_TO_IPADDR_PORT((
const struct sockaddr *)msg->msg_name, &chain_buf->addr, remote_port);
1047 netbuf_fromport(chain_buf) = remote_port;
1049 #if LWIP_NETIF_TX_SINGLE_PBUF 1050 for (i = 0; i < msg->msg_iovlen; i++) {
1051 size += msg->msg_iov[i].iov_len;
1054 if (netbuf_alloc(chain_buf, (
u16_t)size) ==
NULL) {
1060 for (i = 0; i < msg->msg_iovlen; i++) {
1061 MEMCPY(&((
u8_t*)chain_buf->p->payload)[offset], msg->msg_iov[i].iov_base, msg->msg_iov[i].iov_len);
1062 offset += msg->msg_iov[i].iov_len;
1064 #if LWIP_CHECKSUM_ON_COPY 1068 netbuf_set_chksum(chain_buf, chksum);
1075 err = netbuf_ref(chain_buf, msg->msg_iov[0].iov_base, (
u16_t)msg->msg_iov[0].iov_len);
1077 struct netbuf *tail_buf;
1078 size = msg->msg_iov[0].iov_len;
1079 for (i = 1; i < msg->msg_iovlen; i++) {
1080 tail_buf = netbuf_new();
1085 err = netbuf_ref(tail_buf, msg->msg_iov[i].iov_base, (
u16_t)msg->msg_iov[i].iov_len);
1087 netbuf_chain(chain_buf, tail_buf);
1088 size += msg->msg_iov[i].iov_len;
1090 netbuf_delete(tail_buf);
1100 err = netconn_send(sock->conn, chain_buf);
1104 netbuf_delete(chain_buf);
1106 sock_set_errno(sock, err_to_errno(err));
1107 return (err ==
ERR_OK ? size : -1);
1109 sock_set_errno(sock, err_to_errno(
ERR_ARG));
1115 lwip_sendto(
int s,
const void *data,
size_t size,
int flags,
1116 const struct sockaddr *to, socklen_t tolen)
1118 struct lwip_sock *sock;
1124 sock = get_socket(s);
1129 if (NETCONNTYPE_GROUP(netconn_type(sock->conn)) == NETCONN_TCP) {
1131 return lwip_send(s, data, size, flags);
1134 sock_set_errno(sock, err_to_errno(
ERR_ARG));
1139 if ((to !=
NULL) && !SOCK_ADDR_TYPE_MATCH(to, sock)) {
1141 sock_set_errno(sock, err_to_errno(
ERR_VAL));
1146 LWIP_ASSERT(
"lwip_sendto: size must fit in u16_t", size <= 0xffff);
1147 short_size = (
u16_t)size;
1148 LWIP_ERROR(
"lwip_sendto: invalid address", (((to ==
NULL) && (tolen == 0)) ||
1149 (IS_SOCK_ADDR_LEN_VALID(tolen) &&
1150 IS_SOCK_ADDR_TYPE_VALID(to) && IS_SOCK_ADDR_ALIGNED(to))),
1151 sock_set_errno(sock, err_to_errno(
ERR_ARG));
return -1;);
1155 buf.p = buf.ptr =
NULL;
1156 #if LWIP_CHECKSUM_ON_COPY 1160 SOCKADDR_TO_IPADDR_PORT(to, &buf.addr, remote_port);
1163 ip_addr_set_any(NETCONNTYPE_ISIPV6(netconn_type(sock->conn)), &buf.addr);
1165 netbuf_fromport(&buf) = remote_port;
1169 s, data, short_size, flags));
1174 #if LWIP_NETIF_TX_SINGLE_PBUF 1176 if (netbuf_alloc(&buf, short_size) ==
NULL) {
1179 #if LWIP_CHECKSUM_ON_COPY 1180 if (NETCONNTYPE_GROUP(netconn_type(sock->conn)) != NETCONN_RAW) {
1181 u16_t chksum = LWIP_CHKSUM_COPY(buf.p->payload, data, short_size);
1182 netbuf_set_chksum(&buf, chksum);
1186 MEMCPY(buf.p->payload, data, short_size);
1191 err = netbuf_ref(&buf, data, short_size);
1195 err = netconn_send(sock->conn, &buf);
1201 sock_set_errno(sock, err_to_errno(err));
1202 return (err ==
ERR_OK ? short_size : -1);
1206 lwip_socket(
int domain,
int type,
int protocol)
1208 struct netconn *conn;
1218 conn = netconn_new_with_proto_and_callback(DOMAIN_TO_NETCONN_TYPE(domain, NETCONN_RAW),
1219 (
u8_t)protocol, event_callback);
1221 domain == PF_INET ?
"PF_INET" :
"UNKNOWN", protocol));
1224 conn = netconn_new_with_callback(DOMAIN_TO_NETCONN_TYPE(domain,
1225 ((protocol == IPPROTO_UDPLITE) ? NETCONN_UDPLITE : NETCONN_UDP)) ,
1228 domain == PF_INET ?
"PF_INET" :
"UNKNOWN", protocol));
1231 conn = netconn_new_with_callback(DOMAIN_TO_NETCONN_TYPE(domain, NETCONN_TCP), event_callback);
1233 domain == PF_INET ?
"PF_INET" :
"UNKNOWN", protocol));
1236 netconn_set_noautorecved(conn, 1);
1241 domain, type, protocol));
1252 i = alloc_socket(conn, 0);
1255 netconn_delete(conn);
1266 lwip_write(
int s,
const void *data,
size_t size)
1268 return lwip_send(s, data, size, 0);
1272 lwip_writev(
int s,
const struct iovec *iov,
int iovcnt)
1276 msg.msg_name =
NULL;
1277 msg.msg_namelen = 0;
1280 msg.msg_iov = (
struct iovec *)(
size_t)iov;
1281 msg.msg_iovlen = iovcnt;
1282 msg.msg_control =
NULL;
1283 msg.msg_controllen = 0;
1285 return lwip_sendmsg(s, &msg, 0);
1305 lwip_selscan(
int maxfdp1, fd_set *readset_in, fd_set *writeset_in, fd_set *exceptset_in,
1306 fd_set *readset_out, fd_set *writeset_out, fd_set *exceptset_out)
1309 fd_set lreadset, lwriteset, lexceptset;
1310 struct lwip_sock *sock;
1314 FD_ZERO(&lwriteset);
1315 FD_ZERO(&lexceptset);
1320 void* lastdata =
NULL;
1322 u16_t sendevent = 0;
1326 sock = tryget_socket(i);
1328 lastdata = sock->lastdata;
1329 rcvevent = sock->rcvevent;
1330 sendevent = sock->sendevent;
1331 errevent = sock->errevent;
1336 if (readset_in && FD_ISSET(i, readset_in) && ((lastdata !=
NULL) || (rcvevent > 0))) {
1337 FD_SET(i, &lreadset);
1342 if (writeset_in && FD_ISSET(i, writeset_in) && (sendevent != 0)) {
1343 FD_SET(i, &lwriteset);
1348 if (exceptset_in && FD_ISSET(i, exceptset_in) && (errevent != 0)) {
1349 FD_SET(i, &lexceptset);
1355 *readset_out = lreadset;
1356 *writeset_out = lwriteset;
1357 *exceptset_out = lexceptset;
1364 lwip_select(
int maxfdp1, fd_set *readset, fd_set *writeset, fd_set *exceptset,
1365 struct timeval *timeout)
1369 fd_set lreadset, lwriteset, lexceptset;
1371 struct lwip_select_cb select_cb;
1374 #if LWIP_NETCONN_SEM_PER_THREAD 1380 maxfdp1, (
void *)readset, (
void *) writeset, (
void *) exceptset,
1381 timeout ? (
s32_t)timeout->tv_sec : (
s32_t)-1,
1382 timeout ? (
s32_t)timeout->tv_usec : (
s32_t)-1));
1386 nready = lwip_selscan(maxfdp1, readset, writeset, exceptset, &lreadset, &lwriteset, &lexceptset);
1390 if (timeout && timeout->tv_sec == 0 && timeout->tv_usec == 0) {
1394 goto return_copy_fdsets;
1402 select_cb.next =
NULL;
1403 select_cb.prev =
NULL;
1404 select_cb.readset = readset;
1405 select_cb.writeset = writeset;
1406 select_cb.exceptset = exceptset;
1407 select_cb.sem_signalled = 0;
1408 #if LWIP_NETCONN_SEM_PER_THREAD 1409 select_cb.sem = LWIP_NETCONN_THREAD_SEM_GET();
1422 select_cb.next = select_cb_list;
1423 if (select_cb_list !=
NULL) {
1424 select_cb_list->prev = &select_cb;
1426 select_cb_list = &select_cb;
1436 if ((readset && FD_ISSET(i, readset)) ||
1437 (writeset && FD_ISSET(i, writeset)) ||
1438 (exceptset && FD_ISSET(i, exceptset))) {
1439 struct lwip_sock *sock;
1441 sock = tryget_socket(i);
1443 sock->select_waiting++;
1444 LWIP_ASSERT(
"sock->select_waiting > 0", sock->select_waiting > 0);
1459 nready = lwip_selscan(maxfdp1, readset, writeset, exceptset, &lreadset, &lwriteset, &lexceptset);
1466 msectimeout = ((timeout->tv_sec * 1000) + ((timeout->tv_usec + 500)/1000));
1467 if (msectimeout == 0) {
1474 #if LWIP_NETCONN_SEM_PER_THREAD 1482 if ((readset && FD_ISSET(i, readset)) ||
1483 (writeset && FD_ISSET(i, writeset)) ||
1484 (exceptset && FD_ISSET(i, exceptset))) {
1485 struct lwip_sock *sock;
1487 sock = tryget_socket(i);
1492 LWIP_ASSERT(
"sock->select_waiting > 0", sock->select_waiting > 0);
1493 if (sock->select_waiting > 0) {
1494 sock->select_waiting--;
1505 if (select_cb.next !=
NULL) {
1506 select_cb.next->prev = select_cb.prev;
1508 if (select_cb_list == &select_cb) {
1510 select_cb_list = select_cb.next;
1513 select_cb.prev->next = select_cb.next;
1519 #if LWIP_NETCONN_SEM_PER_THREAD 1520 if (select_cb.sem_signalled && (!waited || (waitres ==
SYS_ARCH_TIMEOUT))) {
1539 goto return_copy_fdsets;
1543 nready = lwip_selscan(maxfdp1, readset, writeset, exceptset, &lreadset, &lwriteset, &lexceptset);
1550 *readset = lreadset;
1553 *writeset = lwriteset;
1556 *exceptset = lexceptset;
1566 event_callback(
struct netconn *conn,
enum netconn_evt evt,
u16_t len)
1569 struct lwip_sock *sock;
1570 struct lwip_select_cb *scb;
1571 int last_select_cb_ctr;
1586 if (conn->socket < 0) {
1587 if (evt == NETCONN_EVT_RCVPLUS) {
1597 sock = get_socket(s);
1608 case NETCONN_EVT_RCVPLUS:
1611 case NETCONN_EVT_RCVMINUS:
1614 case NETCONN_EVT_SENDPLUS:
1615 sock->sendevent = 1;
1617 case NETCONN_EVT_SENDMINUS:
1618 sock->sendevent = 0;
1620 case NETCONN_EVT_ERROR:
1628 if (sock->select_waiting == 0) {
1641 for (scb = select_cb_list; scb !=
NULL; scb = scb->next) {
1643 last_select_cb_ctr = select_cb_ctr;
1644 if (scb->sem_signalled == 0) {
1648 if (sock->rcvevent > 0) {
1649 if (scb->readset && FD_ISSET(s, scb->readset)) {
1653 if (sock->sendevent != 0) {
1654 if (!do_signal && scb->writeset && FD_ISSET(s, scb->writeset)) {
1658 if (sock->errevent != 0) {
1659 if (!do_signal && scb->exceptset && FD_ISSET(s, scb->exceptset)) {
1664 scb->sem_signalled = 1;
1674 if (last_select_cb_ctr != select_cb_ctr) {
1687 lwip_shutdown(
int s,
int how)
1689 struct lwip_sock *sock;
1691 u8_t shut_rx = 0, shut_tx = 0;
1695 sock = get_socket(s);
1700 if (sock->conn !=
NULL) {
1701 if (NETCONNTYPE_GROUP(netconn_type(sock->conn)) != NETCONN_TCP) {
1702 sock_set_errno(sock, EOPNOTSUPP);
1706 sock_set_errno(sock, ENOTCONN);
1710 if (how == SHUT_RD) {
1712 }
else if (how == SHUT_WR) {
1714 }
else if (how == SHUT_RDWR) {
1718 sock_set_errno(sock, EINVAL);
1721 err = netconn_shutdown(sock->conn, shut_rx, shut_tx);
1723 sock_set_errno(sock, err_to_errno(err));
1724 return (err ==
ERR_OK ? 0 : -1);
1728 lwip_getaddrname(
int s,
struct sockaddr *name, socklen_t *namelen,
u8_t local)
1730 struct lwip_sock *sock;
1731 union sockaddr_aligned saddr;
1736 sock = get_socket(s);
1743 err = netconn_getaddr(sock->conn, &naddr, &port, local);
1745 sock_set_errno(sock, err_to_errno(err));
1748 IPADDR_PORT_TO_SOCKADDR(&saddr, &naddr, port);
1754 if (*namelen > saddr.sa.sa_len) {
1755 *namelen = saddr.sa.sa_len;
1757 MEMCPY(name, &saddr, *namelen);
1759 sock_set_errno(sock, 0);
1764 lwip_getpeername(
int s,
struct sockaddr *name, socklen_t *namelen)
1766 return lwip_getaddrname(s, name, namelen, 0);
1770 lwip_getsockname(
int s,
struct sockaddr *name, socklen_t *namelen)
1772 return lwip_getaddrname(s, name, namelen, 1);
1776 lwip_getsockopt(
int s,
int level,
int optname,
void *optval, socklen_t *optlen)
1779 struct lwip_sock *sock = get_socket(s);
1780 #if !LWIP_TCPIP_CORE_LOCKING 1781 LWIP_SETGETSOCKOPT_DATA_VAR_DECLARE(data);
1788 if ((
NULL == optval) || (
NULL == optlen)) {
1789 sock_set_errno(sock, EFAULT);
1793 #if LWIP_TCPIP_CORE_LOCKING 1796 err = lwip_getsockopt_impl(s, level, optname, optval, optlen);
1801 #if LWIP_MPU_COMPATIBLE 1803 if (*optlen > LWIP_SETGETSOCKOPT_MAXOPTLEN) {
1804 sock_set_errno(sock, ENOBUFS);
1809 LWIP_SETGETSOCKOPT_DATA_VAR_ALLOC(data, sock);
1810 LWIP_SETGETSOCKOPT_DATA_VAR_REF(data).s = s;
1811 LWIP_SETGETSOCKOPT_DATA_VAR_REF(data).level = level;
1812 LWIP_SETGETSOCKOPT_DATA_VAR_REF(data).optname = optname;
1813 LWIP_SETGETSOCKOPT_DATA_VAR_REF(data).optlen = *optlen;
1814 #if !LWIP_MPU_COMPATIBLE 1815 LWIP_SETGETSOCKOPT_DATA_VAR_REF(data).optval.p = optval;
1817 LWIP_SETGETSOCKOPT_DATA_VAR_REF(data).err = 0;
1818 #if LWIP_NETCONN_SEM_PER_THREAD 1819 LWIP_SETGETSOCKOPT_DATA_VAR_REF(data).completed_sem = LWIP_NETCONN_THREAD_SEM_GET();
1821 LWIP_SETGETSOCKOPT_DATA_VAR_REF(data).completed_sem = &sock->conn->op_completed;
1823 err =
tcpip_callback(lwip_getsockopt_callback, &LWIP_SETGETSOCKOPT_DATA_VAR_REF(data));
1825 LWIP_SETGETSOCKOPT_DATA_VAR_FREE(data);
1826 sock_set_errno(sock, err_to_errno(err));
1832 *optlen = LWIP_SETGETSOCKOPT_DATA_VAR_REF(data).optlen;
1833 #if LWIP_MPU_COMPATIBLE 1834 memcpy(optval, LWIP_SETGETSOCKOPT_DATA_VAR_REF(data).optval,
1835 LWIP_SETGETSOCKOPT_DATA_VAR_REF(data).optlen);
1839 err = LWIP_SETGETSOCKOPT_DATA_VAR_REF(data).err;
1840 LWIP_SETGETSOCKOPT_DATA_VAR_FREE(data);
1843 sock_set_errno(sock, err);
1844 return err ? -1 : 0;
1847 #if !LWIP_TCPIP_CORE_LOCKING 1852 lwip_getsockopt_callback(
void *arg)
1854 struct lwip_setgetsockopt_data *data;
1856 data = (
struct lwip_setgetsockopt_data*)arg;
1858 data->err = lwip_getsockopt_impl(data->s, data->level, data->optname,
1874 lwip_getsockopt_impl(
int s,
int level,
int optname,
void *optval, socklen_t *optlen)
1877 struct lwip_sock *sock = tryget_socket(s);
1890 LWIP_SOCKOPT_CHECK_OPTLEN_CONN_PCB(sock, *optlen,
int);
1891 if (NETCONNTYPE_GROUP(sock->conn->type) != NETCONN_TCP) {
1894 if ((sock->conn->pcb.tcp !=
NULL) && (sock->conn->pcb.tcp->state == LISTEN)) {
1908 LWIP_SOCKOPT_CHECK_OPTLEN_CONN_PCB(sock, *optlen,
int);
1911 s, optname, (*(
int*)optval?
"on":
"off")));
1915 LWIP_SOCKOPT_CHECK_OPTLEN_CONN(sock, *optlen,
int);
1916 switch (NETCONNTYPE_GROUP(netconn_type(sock->conn))) {
1918 *(
int*)optval = SOCK_RAW;
1921 *(
int*)optval = SOCK_STREAM;
1924 *(
int*)optval = SOCK_DGRAM;
1927 *(
int*)optval = netconn_type(sock->conn);
1929 (
"lwip_getsockopt(%d, SOL_SOCKET, SO_TYPE): unrecognized socket type %d\n",
1930 s, *(
int *)optval));
1933 s, *(
int *)optval));
1937 LWIP_SOCKOPT_CHECK_OPTLEN(*optlen,
int);
1939 if (((sock->err == 0) || (sock->err == EINPROGRESS)) && (sock->conn !=
NULL)) {
1940 sock_set_errno(sock, err_to_errno(sock->conn->last_err));
1942 *(
int *)optval = (sock->err == 0xFF ? (
int)-1 : (int)sock->err);
1945 s, *(
int *)optval));
1948 #if LWIP_SO_SNDTIMEO 1950 LWIP_SOCKOPT_CHECK_OPTLEN_CONN(sock, *optlen, LWIP_SO_SNDRCVTIMEO_OPTTYPE);
1951 LWIP_SO_SNDRCVTIMEO_SET(optval, netconn_get_sendtimeout(sock->conn));
1954 #if LWIP_SO_RCVTIMEO 1956 LWIP_SOCKOPT_CHECK_OPTLEN_CONN(sock, *optlen, LWIP_SO_SNDRCVTIMEO_OPTTYPE);
1957 LWIP_SO_SNDRCVTIMEO_SET(optval, netconn_get_recvtimeout(sock->conn));
1962 LWIP_SOCKOPT_CHECK_OPTLEN_CONN(sock, *optlen,
int);
1963 *(
int *)optval = netconn_get_recvbufsize(sock->conn);
1970 struct linger* linger = (
struct linger*)optval;
1971 LWIP_SOCKOPT_CHECK_OPTLEN_CONN(sock, *optlen,
struct linger);
1972 conn_linger = sock->conn->linger;
1973 if (conn_linger >= 0) {
1974 linger->l_onoff = 1;
1975 linger->l_linger = (int)conn_linger;
1977 linger->l_onoff = 0;
1978 linger->l_linger = 0;
1985 LWIP_SOCKOPT_CHECK_OPTLEN_CONN_PCB_TYPE(sock, *optlen,
int, NETCONN_UDP);
1987 if ((udp_flags(sock->conn->pcb.udp) & UDP_FLAGS_UDPLITE) != 0) {
1989 return EAFNOSUPPORT;
1992 *(
int*)optval = (udp_flags(sock->conn->pcb.udp) & UDP_FLAGS_NOCHKSUM) ? 1 : 0;
2007 LWIP_SOCKOPT_CHECK_OPTLEN_CONN_PCB(sock, *optlen,
int);
2008 *(
int*)optval = sock->conn->pcb.ip->ttl;
2010 s, *(
int *)optval));
2013 LWIP_SOCKOPT_CHECK_OPTLEN_CONN_PCB(sock, *optlen,
int);
2014 *(
int*)optval = sock->conn->pcb.ip->tos;
2016 s, *(
int *)optval));
2018 #if LWIP_MULTICAST_TX_OPTIONS 2019 case IP_MULTICAST_TTL:
2020 LWIP_SOCKOPT_CHECK_OPTLEN_CONN_PCB(sock, *optlen,
u8_t);
2021 if (NETCONNTYPE_GROUP(netconn_type(sock->conn)) != NETCONN_UDP) {
2024 *(
u8_t*)optval = sock->conn->pcb.udp->mcast_ttl;
2026 s, *(
int *)optval));
2028 case IP_MULTICAST_IF:
2029 LWIP_SOCKOPT_CHECK_OPTLEN_CONN_PCB(sock, *optlen,
struct in_addr);
2030 if (NETCONNTYPE_GROUP(netconn_type(sock->conn)) != NETCONN_UDP) {
2033 inet_addr_from_ipaddr((
struct in_addr*)optval, udp_get_multicast_netif_addr(sock->conn->pcb.udp));
2035 s, *(
u32_t *)optval));
2037 case IP_MULTICAST_LOOP:
2038 LWIP_SOCKOPT_CHECK_OPTLEN_CONN_PCB(sock, *optlen,
u8_t);
2039 if ((sock->conn->pcb.udp->flags & UDP_FLAGS_MULTICAST_LOOP) != 0) {
2045 s, *(
int *)optval));
2060 LWIP_SOCKOPT_CHECK_OPTLEN_CONN_PCB_TYPE(sock, *optlen,
int, NETCONN_TCP);
2063 *(
int*)optval = tcp_nagle_disabled(sock->conn->pcb.tcp);
2065 s, (*(
int*)optval)?
"on":
"off") );
2068 *(
int*)optval = (
int)sock->conn->pcb.tcp->keep_idle;
2070 s, *(
int *)optval));
2073 #if LWIP_TCP_KEEPALIVE 2075 *(
int*)optval = (
int)(sock->conn->pcb.tcp->keep_idle/1000);
2077 s, *(
int *)optval));
2080 *(
int*)optval = (
int)(sock->conn->pcb.tcp->keep_intvl/1000);
2082 s, *(
int *)optval));
2085 *(
int*)optval = (
int)sock->conn->pcb.tcp->keep_cnt;
2087 s, *(
int *)optval));
2104 LWIP_SOCKOPT_CHECK_OPTLEN_CONN(sock, *optlen,
int);
2106 if (NETCONNTYPE_GROUP(netconn_type(sock->conn)) != NETCONN_TCP) {
2109 *(
int*)optval = ((sock->conn->flags & NETCONN_FLAG_IPV6_V6ONLY) ? 1 : 0);
2111 s, *(
int *)optval));
2122 #if LWIP_UDP && LWIP_UDPLITE 2124 case IPPROTO_UDPLITE:
2126 LWIP_SOCKOPT_CHECK_OPTLEN_CONN_PCB(sock, *optlen,
int);
2128 if (!NETCONNTYPE_ISUDPLITE(netconn_type(sock->conn))) {
2132 case UDPLITE_SEND_CSCOV:
2133 *(
int*)optval = sock->conn->pcb.udp->chksum_len_tx;
2135 s, (*(
int*)optval)) );
2137 case UDPLITE_RECV_CSCOV:
2138 *(
int*)optval = sock->conn->pcb.udp->chksum_len_rx;
2140 s, (*(
int*)optval)) );
2153 #if LWIP_IPV6 && LWIP_RAW 2155 LWIP_SOCKOPT_CHECK_OPTLEN_CONN_PCB_TYPE(sock, *optlen,
int, NETCONN_RAW);
2156 if (sock->conn->pcb.raw->chksum_reqd == 0) {
2157 *(
int *)optval = -1;
2159 *(
int *)optval = sock->conn->pcb.raw->chksum_offset;
2162 s, (*(
int*)optval)) );
2174 s, level, optname));
2183 lwip_setsockopt(
int s,
int level,
int optname,
const void *optval, socklen_t optlen)
2186 struct lwip_sock *sock = get_socket(s);
2187 #if !LWIP_TCPIP_CORE_LOCKING 2188 LWIP_SETGETSOCKOPT_DATA_VAR_DECLARE(data);
2195 if (
NULL == optval) {
2196 sock_set_errno(sock, EFAULT);
2200 #if LWIP_TCPIP_CORE_LOCKING 2203 err = lwip_setsockopt_impl(s, level, optname, optval, optlen);
2208 #if LWIP_MPU_COMPATIBLE 2210 if (optlen > LWIP_SETGETSOCKOPT_MAXOPTLEN) {
2211 sock_set_errno(sock, ENOBUFS);
2216 LWIP_SETGETSOCKOPT_DATA_VAR_ALLOC(data, sock);
2217 LWIP_SETGETSOCKOPT_DATA_VAR_REF(data).s = s;
2218 LWIP_SETGETSOCKOPT_DATA_VAR_REF(data).level = level;
2219 LWIP_SETGETSOCKOPT_DATA_VAR_REF(data).optname = optname;
2220 LWIP_SETGETSOCKOPT_DATA_VAR_REF(data).optlen = optlen;
2221 #if LWIP_MPU_COMPATIBLE 2222 memcpy(LWIP_SETGETSOCKOPT_DATA_VAR_REF(data).optval, optval, optlen);
2224 LWIP_SETGETSOCKOPT_DATA_VAR_REF(data).optval.pc = (
const void*)optval;
2226 LWIP_SETGETSOCKOPT_DATA_VAR_REF(data).err = 0;
2227 #if LWIP_NETCONN_SEM_PER_THREAD 2228 LWIP_SETGETSOCKOPT_DATA_VAR_REF(data).completed_sem = LWIP_NETCONN_THREAD_SEM_GET();
2230 LWIP_SETGETSOCKOPT_DATA_VAR_REF(data).completed_sem = &sock->conn->op_completed;
2232 err =
tcpip_callback(lwip_setsockopt_callback, &LWIP_SETGETSOCKOPT_DATA_VAR_REF(data));
2234 LWIP_SETGETSOCKOPT_DATA_VAR_FREE(data);
2235 sock_set_errno(sock, err_to_errno(err));
2241 err = LWIP_SETGETSOCKOPT_DATA_VAR_REF(data).err;
2242 LWIP_SETGETSOCKOPT_DATA_VAR_FREE(data);
2245 sock_set_errno(sock, err);
2246 return err ? -1 : 0;
2249 #if !LWIP_TCPIP_CORE_LOCKING 2254 lwip_setsockopt_callback(
void *arg)
2256 struct lwip_setgetsockopt_data *data;
2258 data = (
struct lwip_setgetsockopt_data*)arg;
2260 data->err = lwip_setsockopt_impl(data->s, data->level, data->optname,
2276 lwip_setsockopt_impl(
int s,
int level,
int optname,
const void *optval, socklen_t optlen)
2279 struct lwip_sock *sock = tryget_socket(s);
2298 LWIP_SOCKOPT_CHECK_OPTLEN_CONN_PCB(sock, optlen,
int);
2299 if (*(
const int*)optval) {
2305 s, optname, (*(
const int*)optval?
"on":
"off")));
2311 #if LWIP_SO_SNDTIMEO 2313 LWIP_SOCKOPT_CHECK_OPTLEN_CONN(sock, optlen, LWIP_SO_SNDRCVTIMEO_OPTTYPE);
2314 netconn_set_sendtimeout(sock->conn, LWIP_SO_SNDRCVTIMEO_GET_MS(optval));
2317 #if LWIP_SO_RCVTIMEO 2319 LWIP_SOCKOPT_CHECK_OPTLEN_CONN(sock, optlen, LWIP_SO_SNDRCVTIMEO_OPTTYPE);
2320 netconn_set_recvtimeout(sock->conn, (
int)LWIP_SO_SNDRCVTIMEO_GET_MS(optval));
2325 LWIP_SOCKOPT_CHECK_OPTLEN_CONN(sock, optlen,
int);
2326 netconn_set_recvbufsize(sock->conn, *(
const int*)optval);
2332 const struct linger* linger = (
const struct linger*)optval;
2333 LWIP_SOCKOPT_CHECK_OPTLEN_CONN(sock, optlen,
struct linger);
2334 if (linger->l_onoff) {
2335 int lingersec = linger->l_linger;
2336 if (lingersec < 0) {
2339 if (lingersec > 0xFFFF) {
2342 sock->conn->linger = (
s16_t)lingersec;
2344 sock->conn->linger = -1;
2351 LWIP_SOCKOPT_CHECK_OPTLEN_CONN_PCB_TYPE(sock, optlen,
int, NETCONN_UDP);
2353 if ((udp_flags(sock->conn->pcb.udp) & UDP_FLAGS_UDPLITE) != 0) {
2355 return EAFNOSUPPORT;
2358 if (*(
const int*)optval) {
2359 udp_setflags(sock->conn->pcb.udp, udp_flags(sock->conn->pcb.udp) | UDP_FLAGS_NOCHKSUM);
2361 udp_setflags(sock->conn->pcb.udp, udp_flags(sock->conn->pcb.udp) & ~UDP_FLAGS_NOCHKSUM);
2377 LWIP_SOCKOPT_CHECK_OPTLEN_CONN_PCB(sock, optlen,
int);
2378 sock->conn->pcb.ip->ttl = (
u8_t)(*(
const int*)optval);
2380 s, sock->conn->pcb.ip->ttl));
2383 LWIP_SOCKOPT_CHECK_OPTLEN_CONN_PCB(sock, optlen,
int);
2384 sock->conn->pcb.ip->tos = (
u8_t)(*(
const int*)optval);
2386 s, sock->conn->pcb.ip->tos));
2388 #if LWIP_MULTICAST_TX_OPTIONS 2389 case IP_MULTICAST_TTL:
2390 LWIP_SOCKOPT_CHECK_OPTLEN_CONN_PCB_TYPE(sock, optlen,
u8_t, NETCONN_UDP);
2391 sock->conn->pcb.udp->mcast_ttl = (
u8_t)(*(
const u8_t*)optval);
2393 case IP_MULTICAST_IF:
2396 LWIP_SOCKOPT_CHECK_OPTLEN_CONN_PCB_TYPE(sock, optlen,
struct in_addr, NETCONN_UDP);
2397 inet_addr_to_ipaddr(&if_addr, (
const struct in_addr*)optval);
2398 udp_set_multicast_netif_addr(sock->conn->pcb.udp, &if_addr);
2401 case IP_MULTICAST_LOOP:
2402 LWIP_SOCKOPT_CHECK_OPTLEN_CONN_PCB_TYPE(sock, optlen,
u8_t, NETCONN_UDP);
2403 if (*(
const u8_t*)optval) {
2404 udp_setflags(sock->conn->pcb.udp, udp_flags(sock->conn->pcb.udp) | UDP_FLAGS_MULTICAST_LOOP);
2406 udp_setflags(sock->conn->pcb.udp, udp_flags(sock->conn->pcb.udp) & ~UDP_FLAGS_MULTICAST_LOOP);
2411 case IP_ADD_MEMBERSHIP:
2412 case IP_DROP_MEMBERSHIP:
2417 const struct ip_mreq *imr = (
const struct ip_mreq *)optval;
2419 ip4_addr_t multi_addr;
2420 LWIP_SOCKOPT_CHECK_OPTLEN_CONN_PCB_TYPE(sock, optlen,
struct ip_mreq, NETCONN_UDP);
2421 inet_addr_to_ipaddr(&if_addr, &imr->imr_interface);
2422 inet_addr_to_ipaddr(&multi_addr, &imr->imr_multiaddr);
2423 if (optname == IP_ADD_MEMBERSHIP) {
2424 if (!lwip_socket_register_membership(s, &if_addr, &multi_addr)) {
2429 igmp_err = igmp_joingroup(&if_addr, &multi_addr);
2432 igmp_err = igmp_leavegroup(&if_addr, &multi_addr);
2433 lwip_socket_unregister_membership(s, &if_addr, &multi_addr);
2435 if (igmp_err !=
ERR_OK) {
2436 err = EADDRNOTAVAIL;
2453 LWIP_SOCKOPT_CHECK_OPTLEN_CONN_PCB_TYPE(sock, optlen,
int, NETCONN_TCP);
2456 if (*(
const int*)optval) {
2457 tcp_nagle_disable(sock->conn->pcb.tcp);
2459 tcp_nagle_enable(sock->conn->pcb.tcp);
2462 s, (*(
const int *)optval)?
"on":
"off") );
2465 sock->conn->pcb.tcp->keep_idle = (
u32_t)(*(
const int*)optval);
2467 s, sock->conn->pcb.tcp->keep_idle));
2470 #if LWIP_TCP_KEEPALIVE 2472 sock->conn->pcb.tcp->keep_idle = 1000*(
u32_t)(*(
const int*)optval);
2474 s, sock->conn->pcb.tcp->keep_idle));
2477 sock->conn->pcb.tcp->keep_intvl = 1000*(
u32_t)(*(
const int*)optval);
2479 s, sock->conn->pcb.tcp->keep_intvl));
2482 sock->conn->pcb.tcp->keep_cnt = (
u32_t)(*(
const int*)optval);
2484 s, sock->conn->pcb.tcp->keep_cnt));
2502 LWIP_SOCKOPT_CHECK_OPTLEN_CONN_PCB_TYPE(sock, optlen,
int, NETCONN_TCP);
2503 if (*(
const int*)optval) {
2504 sock->conn->flags |= NETCONN_FLAG_IPV6_V6ONLY;
2506 sock->conn->flags &= ~NETCONN_FLAG_IPV6_V6ONLY;
2509 s, ((sock->conn->flags & NETCONN_FLAG_IPV6_V6ONLY) ? 1 : 0)));
2520 #if LWIP_UDP && LWIP_UDPLITE 2522 case IPPROTO_UDPLITE:
2524 LWIP_SOCKOPT_CHECK_OPTLEN_CONN_PCB(sock, optlen,
int);
2526 if (!NETCONNTYPE_ISUDPLITE(netconn_type(sock->conn))) {
2530 case UDPLITE_SEND_CSCOV:
2531 if ((*(
const int*)optval != 0) && ((*(
const int*)optval < 8) || (*(
const int*)optval > 0xffff))) {
2533 sock->conn->pcb.udp->chksum_len_tx = 8;
2535 sock->conn->pcb.udp->chksum_len_tx = (
u16_t)*(
const int*)optval;
2538 s, (*(
const int*)optval)) );
2540 case UDPLITE_RECV_CSCOV:
2541 if ((*(
const int*)optval != 0) && ((*(
const int*)optval < 8) || (*(
const int*)optval > 0xffff))) {
2543 sock->conn->pcb.udp->chksum_len_rx = 8;
2545 sock->conn->pcb.udp->chksum_len_rx = (
u16_t)*(
const int*)optval;
2548 s, (*(
const int*)optval)) );
2561 #if LWIP_IPV6 && LWIP_RAW 2563 LWIP_SOCKOPT_CHECK_OPTLEN_CONN_PCB_TYPE(sock, optlen,
int, NETCONN_RAW);
2564 if (*(
const int *)optval < 0) {
2565 sock->conn->pcb.raw->chksum_reqd = 0;
2566 }
else if (*(
const int *)optval & 1) {
2570 sock->conn->pcb.raw->chksum_reqd = 1;
2571 sock->conn->pcb.raw->chksum_offset = (
u16_t)*(
const int *)optval;
2574 s, sock->conn->pcb.raw->chksum_reqd));
2586 s, level, optname));
2595 lwip_ioctl(
int s,
long cmd,
void *argp)
2597 struct lwip_sock *sock = get_socket(s);
2609 #if LWIP_SO_RCVBUF || LWIP_FIONREAD_LINUXMODE 2612 sock_set_errno(sock, EINVAL);
2615 #if LWIP_FIONREAD_LINUXMODE 2616 if (NETCONNTYPE_GROUP(netconn_type(sock->conn)) != NETCONN_TCP) {
2618 if (sock->lastdata) {
2619 p = ((
struct netbuf *)sock->lastdata)->p;
2621 struct netbuf *rxbuf;
2623 if (sock->rcvevent <= 0) {
2624 *((
u16_t*)argp) = 0;
2626 err = netconn_recv(sock->conn, &rxbuf);
2628 *((
u16_t*)argp) = 0;
2630 sock->lastdata = rxbuf;
2631 *((
u16_t*)argp) = rxbuf->p->tot_len;
2642 if (recv_avail < 0) {
2645 *((
int*)argp) = recv_avail;
2648 if (sock->lastdata) {
2649 struct pbuf *p = (
struct pbuf *)sock->lastdata;
2650 if (NETCONNTYPE_GROUP(netconn_type(sock->conn)) != NETCONN_TCP) {
2651 p = ((
struct netbuf *)p)->p;
2654 buflen -= sock->lastoffset;
2656 *((
int*)argp) += buflen;
2660 sock_set_errno(sock, 0);
2669 if (argp && *(
u32_t*)argp) {
2672 netconn_set_nonblocking(sock->conn, val);
2674 sock_set_errno(sock, 0);
2681 sock_set_errno(sock, ENOSYS);
2690 lwip_fcntl(
int s,
int cmd,
int val)
2692 struct lwip_sock *sock = get_socket(s);
2701 ret = netconn_is_nonblocking(sock->conn) ? O_NONBLOCK : 0;
2702 sock_set_errno(sock, 0);
2705 if ((val & ~O_NONBLOCK) == 0) {
2707 netconn_set_nonblocking(sock->conn, val & O_NONBLOCK);
2709 sock_set_errno(sock, 0);
2711 sock_set_errno(sock, ENOSYS);
2716 sock_set_errno(sock, ENOSYS);
2730 lwip_socket_register_membership(
int s,
const ip4_addr_t *if_addr,
const ip4_addr_t *multi_addr)
2737 for (i = 0; i < LWIP_SOCKET_MAX_MEMBERSHIPS; i++) {
2738 if (socket_ipv4_multicast_memberships[i].sa == 0) {
2739 socket_ipv4_multicast_memberships[i].sa = sa;
2740 ip4_addr_copy(socket_ipv4_multicast_memberships[i].if_addr, *if_addr);
2741 ip4_addr_copy(socket_ipv4_multicast_memberships[i].multi_addr, *multi_addr);
2754 lwip_socket_unregister_membership(
int s,
const ip4_addr_t *if_addr,
const ip4_addr_t *multi_addr)
2761 for (i = 0; i < LWIP_SOCKET_MAX_MEMBERSHIPS; i++) {
2762 if ((socket_ipv4_multicast_memberships[i].sa == sa) &&
2763 ip4_addr_cmp(&socket_ipv4_multicast_memberships[i].if_addr, if_addr) &&
2764 ip4_addr_cmp(&socket_ipv4_multicast_memberships[i].multi_addr, multi_addr)) {
2765 socket_ipv4_multicast_memberships[i].sa = 0;
2766 ip4_addr_set_zero(&socket_ipv4_multicast_memberships[i].if_addr);
2767 ip4_addr_set_zero(&socket_ipv4_multicast_memberships[i].multi_addr);
2777 static void lwip_socket_drop_registered_memberships(
int s)
2786 for (i = 0; i < LWIP_SOCKET_MAX_MEMBERSHIPS; i++) {
2787 if (socket_ipv4_multicast_memberships[i].sa == sa) {
2789 ip_addr_copy_from_ip4(multi_addr, socket_ipv4_multicast_memberships[i].multi_addr);
2790 ip_addr_copy_from_ip4(if_addr, socket_ipv4_multicast_memberships[i].if_addr);
2791 socket_ipv4_multicast_memberships[i].sa = 0;
2792 ip4_addr_set_zero(&socket_ipv4_multicast_memberships[i].if_addr);
2793 ip4_addr_set_zero(&socket_ipv4_multicast_memberships[i].multi_addr);
2795 netconn_join_leave_group(sockets[s].conn, &multi_addr, &if_addr, NETCONN_LEAVE);
#define ip_reset_option(pcb, opt)
#define SYS_ARCH_SET(var, val)
#define LOCK_TCPIP_CORE()
#define MEMCPY(dst, src, len)
void sys_sem_free(sys_sem_t *sem)
#define SYS_ARCH_DECL_PROTECT(lev)
#define LWIP_MPU_COMPATIBLE
err_t sys_sem_new(sys_sem_t *sem, u8_t count)
#define tcpip_callback(f, ctx)
u16_t inet_chksum_pbuf(struct pbuf *p)
u8_t pbuf_free(struct pbuf *p)
#define ip_addr_set_any(is_ipv6, ipaddr)
#define LWIP_ASSERT(message, assertion)
#define ip_addr_debug_print_val(debug, ipaddr)
#define ip_addr_debug_print(debug, ipaddr)
#define UNLOCK_TCPIP_CORE()
u32_t sys_arch_sem_wait(sys_sem_t *sem, u32_t timeout)
u16_t pbuf_copy_partial(struct pbuf *buf, void *dataptr, u16_t len, u16_t offset)
#define SYS_ARCH_PROTECT(lev)
#define SYS_ARCH_UNPROTECT(lev)
#define LWIP_ERROR(message, expression, handler)
#define SYS_ARCH_GET(var, ret)
void sys_sem_signal(sys_sem_t *sem)
#define LWIP_DEBUGF(debug, message)
#define ip_set_option(pcb, opt)
#define LWIP_UNUSED_ARG(x)
#define LWIP_SOCKET_OFFSET
#define ip_get_option(pcb, opt)