diff --git a/components/net/sal/Kconfig b/components/net/sal/Kconfig index 8028868ddbd..57d9e7215ef 100644 --- a/components/net/sal/Kconfig +++ b/components/net/sal/Kconfig @@ -12,6 +12,10 @@ if RT_USING_SAL help The ability that check internet status is provided by RT-Thread. + config SOCKET_TABLE_STEP_LEN + int "Configure socket table step length" + default 4 + menu "Docking with protocol stacks" config SAL_USING_LWIP bool "Docking with lwIP stack" diff --git a/components/net/sal/include/sal_socket.h b/components/net/sal/include/sal_socket.h index e7086a1b93b..527f3fe440b 100644 --- a/components/net/sal/include/sal_socket.h +++ b/components/net/sal/include/sal_socket.h @@ -33,75 +33,75 @@ typedef uint16_t in_port_t; #endif /* Socket protocol types (TCP/UDP/RAW) */ -#define SOCK_STREAM 1 -#define SOCK_DGRAM 2 -#define SOCK_RAW 3 -#define SOCK_PACKET 10 +#define SOCK_STREAM 1 +#define SOCK_DGRAM 2 +#define SOCK_RAW 3 +#define SOCK_PACKET 10 -#define SOCK_NONBLOCK 04000 -#define SOCK_CLOEXEC 02000000 +#define SOCK_NONBLOCK 04000 +#define SOCK_CLOEXEC 02000000 -#define SOCK_MAX (SOCK_CLOEXEC + 1) +#define SOCK_MAX (SOCK_CLOEXEC + 1) /* 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) */ +#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) */ -#define SO_PASSCRED 16 -#define SO_PEERCRED 17 +#define SO_PASSCRED 16 +#define SO_PEERCRED 17 -#define SO_BINDTODEVICE 25 -#define SO_ATTACH_FILTER 26 -#define SO_DETACH_FILTER 27 +#define SO_BINDTODEVICE 25 +#define SO_ATTACH_FILTER 26 +#define SO_DETACH_FILTER 27 -#define SO_SNDBUFFORCE 32 -#define SO_RCVBUFFORCE 33 -#define SO_PROTOCOL 38 -#define SO_DOMAIN 39 +#define SO_SNDBUFFORCE 32 +#define SO_RCVBUFFORCE 33 +#define SO_PROTOCOL 38 +#define SO_DOMAIN 39 /* 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_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 */ /* Level number for (get/set)sockopt() to apply to socket itself */ -#define SOL_SOCKET 0xfff /* options for socket level */ -#define SOL_NETLINK 270 - -#define AF_UNSPEC 0 -#define AF_UNIX 1 -#define AF_INET 2 -#define AF_INET6 10 -#define AF_NETLINK 16 -#define AF_CAN 29 /* Controller Area Network */ -#define AF_AT 45 /* AT socket */ -#define AF_WIZ 46 /* WIZnet socket */ -#define PF_UNIX AF_UNIX -#define PF_INET AF_INET -#define PF_INET6 AF_INET6 -#define PF_NETLINK AF_NETLINK -#define PF_UNSPEC AF_UNSPEC -#define PF_CAN AF_CAN -#define PF_AT AF_AT -#define PF_WIZ AF_WIZ - -#define AF_MAX (AF_WIZ + 1) /* For now.. */ +#define SOL_SOCKET 0xfff /* options for socket level */ +#define SOL_NETLINK 270 + +#define AF_UNSPEC 0 +#define AF_UNIX 1 +#define AF_INET 2 +#define AF_INET6 10 +#define AF_NETLINK 16 +#define AF_CAN 29 /* Controller Area Network */ +#define AF_AT 45 /* AT socket */ +#define AF_WIZ 46 /* WIZnet socket */ +#define PF_UNIX AF_UNIX +#define PF_INET AF_INET +#define PF_INET6 AF_INET6 +#define PF_NETLINK AF_NETLINK +#define PF_UNSPEC AF_UNSPEC +#define PF_CAN AF_CAN +#define PF_AT AF_AT +#define PF_WIZ AF_WIZ + +#define AF_MAX (AF_WIZ + 1) /* For now.. */ #define IPPROTO_IP 0 #define IPPROTO_ICMP 1 @@ -113,33 +113,33 @@ typedef uint16_t in_port_t; #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_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_ERRQUEUE 0x2000 /* Fetch message from error queue */ -#define MSG_CONFIRM 0x0800 /* Confirm path validity */ +#define MSG_ERRQUEUE 0x2000 /* Fetch message from error queue */ +#define MSG_CONFIRM 0x0800 /* Confirm path validity */ /* Options for level IPPROTO_IP */ -#define IP_TOS 1 -#define IP_TTL 2 +#define IP_TOS 1 +#define IP_TTL 2 /* 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 */ +#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 and types related to multicast membership */ #define IP_ADD_MEMBERSHIP 3 #define IP_DROP_MEMBERSHIP 4 /* Options and types for UDP multicast traffic handling */ -#define IP_MULTICAST_TTL 5 -#define IP_MULTICAST_IF 6 -#define IP_MULTICAST_LOOP 7 +#define IP_MULTICAST_TTL 5 +#define IP_MULTICAST_IF 6 +#define IP_MULTICAST_LOOP 7 typedef struct ip_mreq { @@ -148,25 +148,25 @@ typedef struct ip_mreq } ip_mreq; /* The Type of Service provides an indication of the abstract parameters of the quality of service desired */ -#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 +#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 */ -#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 +#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 #define SCM_RIGHTS 0x01 /* rw: access rights (array of int) */ #define SCM_CREDENTIALS 0x02 /* rw: struct ucred */ @@ -174,16 +174,16 @@ typedef struct ip_mreq /* Options for shatdown type */ #ifndef SHUT_RD - #define SHUT_RD 0 - #define SHUT_WR 1 - #define SHUT_RDWR 2 +#define SHUT_RD 0 +#define SHUT_WR 1 +#define SHUT_RDWR 2 #endif struct sockaddr { - uint8_t sa_len; - sa_family_t sa_family; - char sa_data[14]; + uint8_t sa_len; + sa_family_t sa_family; + char sa_data[14]; }; /* Structure describing the address of an AF_LOCAL (aka AF_UNIX) socket. */ @@ -197,35 +197,35 @@ struct sockaddr_un /* members are in network byte order */ struct sockaddr_in { - uint8_t sin_len; - sa_family_t sin_family; - in_port_t sin_port; + uint8_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]; + char sin_zero[SIN_ZERO_LEN]; }; #endif /* NETDEV_IPV4 */ #if NETDEV_IPV6 struct sockaddr_in6 { - uint8_t sin6_len; /* length of this structure */ - sa_family_t sin6_family; /* AF_INET6 */ - in_port_t sin6_port; /* Transport layer port # */ - uint32_t sin6_flowinfo; /* IPv6 flow information */ - struct in6_addr sin6_addr; /* IPv6 address */ - uint32_t sin6_scope_id; /* Set of interfaces for scope */ + uint8_t sin6_len; /* length of this structure */ + sa_family_t sin6_family; /* AF_INET6 */ + in_port_t sin6_port; /* Transport layer port # */ + uint32_t sin6_flowinfo; /* IPv6 flow information */ + struct in6_addr sin6_addr; /* IPv6 address */ + uint32_t sin6_scope_id; /* Set of interfaces for scope */ }; #endif /* NETDEV_IPV6 */ struct sockaddr_storage { - uint8_t s2_len; - sa_family_t ss_family; - char s2_data1[2]; - uint32_t s2_data2[3]; + uint8_t s2_len; + sa_family_t ss_family; + char s2_data1[2]; + uint32_t s2_data2[3]; #if NETDEV_IPV6 - uint32_t s2_data3[3]; + uint32_t s2_data3[3]; #endif /* NETDEV_IPV6 */ }; @@ -241,26 +241,26 @@ struct iovec 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; + 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 { - size_t cmsg_len; /* number of bytes, including header */ - int cmsg_level; /* originating protocol */ - int cmsg_type; /* protocol-specific type */ + size_t cmsg_len; /* number of bytes, including header */ + int cmsg_level; /* originating protocol */ + int cmsg_type; /* protocol-specific type */ }; #define CMSG_NXTHDR(mhdr, cmsg) cmsg_nxthdr((mhdr), (cmsg)) -#define CMSG_ALIGN(len) (((len) + sizeof(long) - 1) & ~(sizeof(long)-1)) +#define CMSG_ALIGN(len) (((len) + sizeof(long) - 1) & ~(sizeof(long) - 1)) #define CMSG_DATA(cmsg) ((void *)(cmsg) + sizeof(struct cmsghdr)) #define CMSG_SPACE(len) (sizeof(struct cmsghdr) + CMSG_ALIGN(len)) @@ -269,10 +269,10 @@ struct cmsghdr #define __CMSG_FIRSTHDR(ctl, len) \ ((len) >= sizeof(struct cmsghdr) ? (struct cmsghdr *)(ctl) : (struct cmsghdr *)NULL) -#define CMSG_FIRSTHDR(msg) __CMSG_FIRSTHDR((msg)->msg_control, (msg)->msg_controllen) -#define CMSG_OK(mhdr, cmsg) \ +#define CMSG_FIRSTHDR(msg) __CMSG_FIRSTHDR((msg)->msg_control, (msg)->msg_controllen) +#define CMSG_OK(mhdr, cmsg) \ ((cmsg)->cmsg_len >= sizeof(struct cmsghdr) && \ - (cmsg)->cmsg_len <= (unsigned long)((mhdr)->msg_controllen - ((char *)(cmsg) - (char *)(mhdr)->msg_control))) + (cmsg)->cmsg_len <= (unsigned long)((mhdr)->msg_controllen - ((char *)(cmsg) - (char *)(mhdr)->msg_control))) #define for_each_cmsghdr(cmsg, msg) \ for (cmsg = CMSG_FIRSTHDR(msg); cmsg; cmsg = CMSG_NXTHDR(msg, cmsg)) @@ -296,7 +296,7 @@ static inline struct cmsghdr *cmsg_nxthdr(struct msghdr *_msg, struct cmsghdr *_ return __cmsg_nxthdr(_msg->msg_control, _msg->msg_controllen, _cmsg); } -#define IFNAMSIZ 16 +#define IFNAMSIZ 16 struct sal_ifmap { unsigned long int mem_start; @@ -333,18 +333,18 @@ struct sal_ifreq int sal_accept(int socket, struct sockaddr *addr, socklen_t *addrlen); int sal_bind(int socket, const struct sockaddr *name, socklen_t namelen); int sal_shutdown(int socket, int how); -int sal_getpeername (int socket, struct sockaddr *name, socklen_t *namelen); -int sal_getsockname (int socket, struct sockaddr *name, socklen_t *namelen); -int sal_getsockopt (int socket, int level, int optname, void *optval, socklen_t *optlen); -int sal_setsockopt (int socket, int level, int optname, const void *optval, socklen_t optlen); +int sal_getpeername(int socket, struct sockaddr *name, socklen_t *namelen); +int sal_getsockname(int socket, struct sockaddr *name, socklen_t *namelen); +int sal_getsockopt(int socket, int level, int optname, void *optval, socklen_t *optlen); +int sal_setsockopt(int socket, int level, int optname, const void *optval, socklen_t optlen); int sal_connect(int socket, const struct sockaddr *name, socklen_t namelen); int sal_listen(int socket, int backlog); int sal_sendmsg(int socket, const struct msghdr *message, int flags); int sal_recvmsg(int socket, struct msghdr *message, int flags); int sal_recvfrom(int socket, void *mem, size_t len, int flags, - struct sockaddr *from, socklen_t *fromlen); + struct sockaddr *from, socklen_t *fromlen); int sal_sendto(int socket, const void *dataptr, size_t size, int flags, - const struct sockaddr *to, socklen_t tolen); + const struct sockaddr *to, socklen_t tolen); int sal_socket(int domain, int type, int protocol); int sal_socketpair(int domain, int type, int protocol, int *fds); int sal_closesocket(int socket); diff --git a/components/net/sal/src/sal_socket.c b/components/net/sal/src/sal_socket.c index ba6a65fd1d8..fa9eb9cc746 100644 --- a/components/net/sal/src/sal_socket.c +++ b/components/net/sal/src/sal_socket.c @@ -39,11 +39,21 @@ #error "The system workqueue stack size must more than 1536 bytes" #endif -#define DBG_TAG "sal.skt" -#define DBG_LVL DBG_INFO +#define DBG_TAG "sal.skt" +#define DBG_LVL DBG_INFO #include -#define SOCKET_TABLE_STEP_LEN 4 +#define VALID_PROTOCOL(protocol) ((protocol) >= 0 && (protocol) <= IPPROTO_RAW) +#define VALID_COMBO(domain, type, protocol) \ + ( \ + (((domain) == AF_INET || (domain) == AF_INET6) && \ + (((type) == SOCK_STREAM && ((protocol) == 0 || (protocol) == IPPROTO_TCP)) || \ + ((type) == SOCK_DGRAM && ((protocol) == 0 || (protocol) == IPPROTO_UDP)) || \ + ((type) == SOCK_RAW && ((protocol) == IPPROTO_RAW)) \ + )) || \ + ((domain) == AF_UNIX && (type) == SOCK_STREAM && (protocol) == 0) || \ + ((domain) == AF_NETLINK && (type) == SOCK_RAW && (protocol) == 0) \ + ) /* the socket table used to dynamic allocate sockets */ struct sal_socket_table @@ -64,7 +74,7 @@ struct ifconf int ifc_len; /* Size of buffer. */ union { - char* ifcu_buf; + char *ifcu_buf; struct sal_ifreq *ifcu_req; } ifc_ifcu; }; @@ -80,49 +90,57 @@ static struct rt_mutex sal_core_lock; static rt_bool_t init_ok = RT_FALSE; static struct sal_netdev_res_table sal_dev_res_tbl[SAL_SOCKETS_NUM]; -#define IS_SOCKET_PROTO_TLS(sock) (((sock)->protocol == PROTOCOL_TLS) || \ - ((sock)->protocol == PROTOCOL_DTLS)) -#define SAL_SOCKOPS_PROTO_TLS_VALID(sock, name) (proto_tls && (proto_tls->ops->name) && IS_SOCKET_PROTO_TLS(sock)) - -#define SAL_SOCKOPT_PROTO_TLS_EXEC(sock, name, optval, optlen) \ -do { \ - if (SAL_SOCKOPS_PROTO_TLS_VALID(sock, name)){ \ - return proto_tls->ops->name((sock)->user_data_tls, (optval), (optlen)); \ - } \ -}while(0) \ - -#define SAL_SOCKET_OBJ_GET(sock, socket) \ -do { \ - (sock) = sal_get_socket(socket); \ - if ((sock) == RT_NULL) { \ - return -1; \ - } \ -}while(0) \ - -#define SAL_NETDEV_IS_UP(netdev) \ -do { \ - if (!netdev_is_up(netdev)) { \ - return -1; \ - } \ -}while(0) \ - -#define SAL_NETDEV_SOCKETOPS_VALID(netdev, pf, ops) \ -do { \ - (pf) = (struct sal_proto_family *) netdev->sal_user_data; \ - if ((pf)->skt_ops->ops == RT_NULL){ \ - return -1; \ - } \ -}while(0) \ - -#define SAL_NETDEV_NETDBOPS_VALID(netdev, pf, ops) \ - ((netdev) && netdev_is_up(netdev) && \ - ((pf) = (struct sal_proto_family *) (netdev)->sal_user_data) != RT_NULL && \ - (pf)->netdb_ops->ops) \ - -#define SAL_NETDBOPS_VALID(netdev, pf, ops) \ - ((netdev) && \ - ((pf) = (struct sal_proto_family *) (netdev)->sal_user_data) != RT_NULL && \ - (pf)->netdb_ops->ops) \ +#define IS_SOCKET_PROTO_TLS(sock) (((sock)->protocol == PROTOCOL_TLS) || \ + ((sock)->protocol == PROTOCOL_DTLS)) +#define SAL_SOCKOPS_PROTO_TLS_VALID(sock, name) (proto_tls && (proto_tls->ops->name) && IS_SOCKET_PROTO_TLS(sock)) + +#define SAL_SOCKOPT_PROTO_TLS_EXEC(sock, name, optval, optlen) \ + do \ + { \ + if (SAL_SOCKOPS_PROTO_TLS_VALID(sock, name)) \ + { \ + return proto_tls->ops->name((sock)->user_data_tls, (optval), (optlen)); \ + } \ + } while (0) + +#define SAL_SOCKET_OBJ_GET(sock, socket) \ + do \ + { \ + (sock) = sal_get_socket(socket); \ + if ((sock) == RT_NULL) \ + { \ + return -1; \ + } \ + } while (0) + +#define SAL_NETDEV_IS_UP(netdev) \ + do \ + { \ + if (!netdev_is_up(netdev)) \ + { \ + return -1; \ + } \ + } while (0) + +#define SAL_NETDEV_SOCKETOPS_VALID(netdev, pf, ops) \ + do \ + { \ + (pf) = (struct sal_proto_family *)netdev->sal_user_data; \ + if ((pf)->skt_ops->ops == RT_NULL) \ + { \ + return -1; \ + } \ + } while (0) + +#define SAL_NETDEV_NETDBOPS_VALID(netdev, pf, ops) \ + ((netdev) && netdev_is_up(netdev) && \ + ((pf) = (struct sal_proto_family *)(netdev)->sal_user_data) != RT_NULL && \ + (pf)->netdb_ops->ops) + +#define SAL_NETDBOPS_VALID(netdev, pf, ops) \ + ((netdev) && \ + ((pf) = (struct sal_proto_family *)(netdev)->sal_user_data) != RT_NULL && \ + (pf)->netdb_ops->ops) /** * SAL (Socket Abstraction Layer) initialize. @@ -151,7 +169,7 @@ int sal_init(void) } /*init the dev_res table */ - rt_memset(sal_dev_res_tbl, 0, sizeof(sal_dev_res_tbl)); + rt_memset(sal_dev_res_tbl, 0, sizeof(sal_dev_res_tbl)); /* create sal socket lock */ rt_mutex_init(&sal_core_lock, "sal_lock", RT_IPC_FLAG_PRIO); @@ -167,12 +185,12 @@ INIT_COMPONENT_EXPORT(sal_init); /* check SAL network interface device internet status */ static void check_netdev_internet_up_work(struct rt_work *work, void *work_data) { -#define SAL_INTERNET_VERSION 0x00 -#define SAL_INTERNET_BUFF_LEN 12 -#define SAL_INTERNET_TIMEOUT (2) +#define SAL_INTERNET_VERSION 0x00 +#define SAL_INTERNET_BUFF_LEN 12 +#define SAL_INTERNET_TIMEOUT (2) -#define SAL_INTERNET_HOST "link.rt-thread.org" -#define SAL_INTERNET_PORT 8101 +#define SAL_INTERNET_HOST "link.rt-thread.org" +#define SAL_INTERNET_PORT 8101 #define SAL_INTERNET_MONTH_LEN 4 #define SAL_INTERNET_DATE_LEN 16 @@ -186,11 +204,11 @@ static void check_netdev_internet_up_work(struct rt_work *work, void *work_data) socklen_t addr_len = sizeof(struct sockaddr_in); char send_data[SAL_INTERNET_BUFF_LEN], recv_data = 0; - const char month[][SAL_INTERNET_MONTH_LEN] = {"Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"}; + const char month[][SAL_INTERNET_MONTH_LEN] = { "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" }; char date[SAL_INTERNET_DATE_LEN]; unsigned int moth_num = 0; - struct sal_proto_family *pf = (struct sal_proto_family *) netdev->sal_user_data; + struct sal_proto_family *pf = (struct sal_proto_family *)netdev->sal_user_data; const struct sal_socket_ops *skt_ops; if (work) @@ -205,7 +223,7 @@ static void check_netdev_internet_up_work(struct rt_work *work, void *work_data) goto __exit; } - host = (struct hostent *) pf->netdb_ops->gethostbyname(SAL_INTERNET_HOST); + host = (struct hostent *)pf->netdb_ops->gethostbyname(SAL_INTERNET_HOST); if (host == RT_NULL) { result = -RT_ERROR; @@ -228,8 +246,8 @@ static void check_netdev_internet_up_work(struct rt_work *work, void *work_data) timeout.tv_usec = 0; /* set receive and send timeout */ - skt_ops->setsockopt(sockfd, SOL_SOCKET, SO_RCVTIMEO, (void *) &timeout, sizeof(timeout)); - skt_ops->setsockopt(sockfd, SOL_SOCKET, SO_SNDTIMEO, (void *) &timeout, sizeof(timeout)); + skt_ops->setsockopt(sockfd, SOL_SOCKET, SO_RCVTIMEO, (void *)&timeout, sizeof(timeout)); + skt_ops->setsockopt(sockfd, SOL_SOCKET, SO_SNDTIMEO, (void *)&timeout, sizeof(timeout)); /* get build moth value*/ rt_memset(date, 0x00, SAL_INTERNET_DATE_LEN); @@ -333,7 +351,7 @@ int sal_check_netdev_internet_up(struct netdev *netdev) int sal_proto_tls_register(const struct sal_proto_tls *pt) { RT_ASSERT(pt); - proto_tls = (struct sal_proto_tls *) pt; + proto_tls = (struct sal_proto_tls *)pt; return 0; } @@ -352,7 +370,7 @@ struct sal_socket *sal_get_socket(int socket) socket = socket - SAL_SOCKET_OFFSET; - if (socket < 0 || socket >= (int) st->max_socket) + if (socket < 0 || socket >= (int)st->max_socket) { return RT_NULL; } @@ -416,8 +434,7 @@ int sal_netdev_cleanup(struct netdev *netdev) { rt_thread_mdelay(100); } - } - while (find_dev); + } while (find_dev); return 0; } @@ -434,35 +451,55 @@ int sal_netdev_cleanup(struct netdev *netdev) * -1 : input the wrong family * -2 : input the wrong socket type * -3 : get network interface failed + * -4 : invalid protocol or combo */ static int socket_init(int family, int type, int protocol, struct sal_socket **res) { - struct sal_socket *sock; struct sal_proto_family *pf; struct netdev *netdv_def = netdev_default; struct netdev *netdev = RT_NULL; rt_bool_t flag = RT_FALSE; + /* Existing range checks for family and type */ if (family < 0 || family > AF_MAX) { + LOG_E("Invalid family: %d (must be 0 ~ %d)", family, AF_MAX); return -1; } if (type < 0 || type > SOCK_MAX) { + LOG_E("Invalid type: %d (must be 0 ~ %d)", type, SOCK_MAX); return -2; } + /* Range check for protocol */ + if (!VALID_PROTOCOL(protocol)) + { + LOG_E("Invalid protocol: %d (must be 0 ~ %d)", protocol, IPPROTO_RAW); + rt_set_errno(EINVAL); + return -4; + } + sock = *res; sock->domain = family; sock->type = type; sock->protocol = protocol; + /* Combo compatibility check */ + if (!VALID_COMBO(family, type, protocol)) + { + LOG_E("Invalid combo: domain=%d, type=%d, protocol=%d", family, type, protocol); + rt_set_errno(EINVAL); + return -4; + } + + /* Existing netdev selection logic */ if (netdv_def && netdev_is_up(netdv_def)) { /* check default network interface device protocol family */ - pf = (struct sal_proto_family *) netdv_def->sal_user_data; + pf = (struct sal_proto_family *)netdv_def->sal_user_data; if (pf != RT_NULL && pf->skt_ops && (pf->family == family || pf->sec_family == family)) { sock->netdev = netdv_def; @@ -483,6 +520,8 @@ static int socket_init(int family, int type, int protocol, struct sal_socket **r sock->netdev = netdev; } + LOG_D("Socket init success: domain=%d, type=%d, protocol=%d, netdev=%s", + family, type, protocol, sock->netdev ? sock->netdev->name : "default"); return 0; } @@ -491,7 +530,7 @@ static int socket_alloc(struct sal_socket_table *st, int f_socket) int idx; /* find an empty socket entry */ - for (idx = f_socket; idx < (int) st->max_socket; idx++) + for (idx = f_socket; idx < (int)st->max_socket; idx++) { if (st->sockets[idx] == RT_NULL) { @@ -500,7 +539,7 @@ static int socket_alloc(struct sal_socket_table *st, int f_socket) } /* allocate a larger sockte container */ - if (idx == (int) st->max_socket && st->max_socket < SAL_SOCKETS_NUM) + if (idx == (int)st->max_socket && st->max_socket < SAL_SOCKETS_NUM) { int cnt, index; struct sal_socket **sockets; @@ -524,7 +563,7 @@ static int socket_alloc(struct sal_socket_table *st, int f_socket) } /* allocate 'struct sal_socket' */ - if (idx < (int) st->max_socket && st->sockets[idx] == RT_NULL) + if (idx < (int)st->max_socket && st->sockets[idx] == RT_NULL) { st->sockets[idx] = rt_calloc(1, sizeof(struct sal_socket)); if (st->sockets[idx] == RT_NULL) @@ -558,7 +597,7 @@ static int socket_new(void) idx = socket_alloc(st, 0); /* can't find an empty sal socket entry */ - if (idx == (int) st->max_socket) + if (idx == (int)st->max_socket) { idx = -(1 + SAL_SOCKET_OFFSET); goto __result; @@ -585,7 +624,7 @@ static void socket_delete(int socket) int idx; idx = socket - SAL_SOCKET_OFFSET; - if (idx < 0 || idx >= (int) st->max_socket) + if (idx < 0 || idx >= (int)st->max_socket) { return; } @@ -653,7 +692,7 @@ int sal_accept(int socket, struct sockaddr *addr, socklen_t *addrlen) static void sal_sockaddr_to_ipaddr(const struct sockaddr *name, ip_addr_t *local_ipaddr) { - const struct sockaddr_in *svr_addr = (const struct sockaddr_in *) name; + const struct sockaddr_in *svr_addr = (const struct sockaddr_in *)name; #if NETDEV_IPV4 && NETDEV_IPV6 local_ipaddr->u_addr.ip4.addr = svr_addr->sin_addr.s_addr; @@ -838,7 +877,7 @@ int sal_setsockopt(int socket, int level, int optname, const void *optval, sockl } else { - return pf->skt_ops->setsockopt((int) sock->user_data, level, optname, optval, optlen); + return pf->skt_ops->setsockopt((int)sock->user_data, level, optname, optval, optlen); } #else return pf->skt_ops->setsockopt((int)(size_t)sock->user_data, level, optname, optval, optlen); @@ -1016,7 +1055,7 @@ int sal_sendto(int socket, const void *dataptr, size_t size, int flags, } else { - return pf->skt_ops->sendto((int) sock->user_data, dataptr, size, flags, to, tolen); + return pf->skt_ops->sendto((int)sock->user_data, dataptr, size, flags, to, tolen); } #else return pf->skt_ops->sendto((int)(size_t)sock->user_data, dataptr, size, flags, to, tolen); @@ -1051,7 +1090,7 @@ int sal_socket(int domain, int type, int protocol) { LOG_E("SAL socket protocol family input failed, return error %d.", retval); socket_delete(socket); - return -1; + return retval; } /* valid the network interface socket opreation */ @@ -1147,13 +1186,13 @@ int sal_closesocket(int socket) #define ARPHRD_ETHER 1 /* Ethernet 10/100Mbps. */ #define ARPHRD_LOOPBACK 772 /* Loopback device. */ -#define IFF_UP 0x1 -#define IFF_RUNNING 0x40 -#define IFF_NOARP 0x80 +#define IFF_UP 0x1 +#define IFF_RUNNING 0x40 +#define IFF_NOARP 0x80 int sal_ioctlsocket(int socket, long cmd, void *arg) { - rt_slist_t *node = RT_NULL; + rt_slist_t *node = RT_NULL; struct netdev *netdev = RT_NULL; struct netdev *cur_netdev_list = netdev_list; struct sal_socket *sock; @@ -1174,13 +1213,13 @@ int sal_ioctlsocket(int socket, long cmd, void *arg) if (!strcmp(ifr->ifr_ifrn.ifrn_name, sock->netdev->name)) { addr_in = (struct sockaddr_in *)&(ifr->ifr_ifru.ifru_addr); - #if NETDEV_IPV4 && NETDEV_IPV6 +#if NETDEV_IPV4 && NETDEV_IPV6 addr_in->sin_addr.s_addr = sock->netdev->ip_addr.u_addr.ip4.addr; - #elif NETDEV_IPV4 +#elif NETDEV_IPV4 addr_in->sin_addr.s_addr = sock->netdev->ip_addr.addr; - #elif NETDEV_IPV6 - #error "not only support IPV6" - #endif /* NETDEV_IPV4 && NETDEV_IPV6*/ +#elif NETDEV_IPV6 +#error "not only support IPV6" +#endif /* NETDEV_IPV4 && NETDEV_IPV6*/ return 0; } else @@ -1197,13 +1236,13 @@ int sal_ioctlsocket(int socket, long cmd, void *arg) if (!strcmp(ifr->ifr_ifrn.ifrn_name, netdev->name)) { addr_in = (struct sockaddr_in *)&(ifr->ifr_ifru.ifru_addr); - #if NETDEV_IPV4 && NETDEV_IPV6 +#if NETDEV_IPV4 && NETDEV_IPV6 addr_in->sin_addr.s_addr = netdev->ip_addr.u_addr.ip4.addr; - #elif NETDEV_IPV4 +#elif NETDEV_IPV4 addr_in->sin_addr.s_addr = netdev->ip_addr.addr; - #elif NETDEV_IPV6 - #error "Do not only support IPV6" - #endif /* NETDEV_IPV4 && NETDEV_IPV6 */ +#elif NETDEV_IPV6 +#error "Do not only support IPV6" +#endif /* NETDEV_IPV4 && NETDEV_IPV6 */ return 0; } @@ -1245,13 +1284,13 @@ int sal_ioctlsocket(int socket, long cmd, void *arg) if (!strcmp(ifr->ifr_ifrn.ifrn_name, sock->netdev->name)) { addr_in = (struct sockaddr_in *)&(ifr->ifr_ifru.ifru_netmask); - #if NETDEV_IPV4 && NETDEV_IPV6 +#if NETDEV_IPV4 && NETDEV_IPV6 addr_in->sin_addr.s_addr = sock->netdev->netmask.u_addr.ip4.addr; - #elif NETDEV_IPV4 +#elif NETDEV_IPV4 addr_in->sin_addr.s_addr = sock->netdev->netmask.addr; - #elif NETDEV_IPV6 - #error "not only support IPV6" - #endif /* NETDEV_IPV4 && NETDEV_IPV6*/ +#elif NETDEV_IPV6 +#error "not only support IPV6" +#endif /* NETDEV_IPV4 && NETDEV_IPV6*/ return 0; } else @@ -1268,13 +1307,13 @@ int sal_ioctlsocket(int socket, long cmd, void *arg) if (!strcmp(ifr->ifr_ifrn.ifrn_name, netdev->name)) { addr_in = (struct sockaddr_in *)&(ifr->ifr_ifru.ifru_netmask); - #if NETDEV_IPV4 && NETDEV_IPV6 +#if NETDEV_IPV4 && NETDEV_IPV6 addr_in->sin_addr.s_addr = netdev->netmask.u_addr.ip4.addr; - #elif NETDEV_IPV4 +#elif NETDEV_IPV4 addr_in->sin_addr.s_addr = netdev->netmask.addr; - #elif NETDEV_IPV6 - #error "not only support IPV6" - #endif /* NETDEV_IPV4 && NETDEV_IPV6*/ +#elif NETDEV_IPV6 +#error "not only support IPV6" +#endif /* NETDEV_IPV4 && NETDEV_IPV6*/ return 0; } } @@ -1312,18 +1351,18 @@ int sal_ioctlsocket(int socket, long cmd, void *arg) } case SIOCGIFHWADDR: - if (!strcmp(ifr->ifr_ifrn.ifrn_name,sock->netdev->name)) + if (!strcmp(ifr->ifr_ifrn.ifrn_name, sock->netdev->name)) { addr = (struct sockaddr *)&(ifr->ifr_ifru.ifru_hwaddr); #ifdef RT_USING_LWP if (!strcmp("lo", sock->netdev->name)) { - struct musl_ifreq * musl_ifreq_tmp = (struct musl_ifreq *)arg; + struct musl_ifreq *musl_ifreq_tmp = (struct musl_ifreq *)arg; musl_ifreq_tmp->ifr_ifru.ifru_hwaddr.sa_family = ARPHRD_LOOPBACK; } else { - struct musl_ifreq * musl_ifreq_tmp = (struct musl_ifreq *)arg; + struct musl_ifreq *musl_ifreq_tmp = (struct musl_ifreq *)arg; musl_ifreq_tmp->ifr_ifru.ifru_hwaddr.sa_family = ARPHRD_ETHER; } #endif @@ -1347,12 +1386,12 @@ int sal_ioctlsocket(int socket, long cmd, void *arg) #ifdef RT_USING_LWP if (!strcmp("lo", netdev->name)) { - struct musl_ifreq * musl_ifreq_tmp = (struct musl_ifreq *)arg; + struct musl_ifreq *musl_ifreq_tmp = (struct musl_ifreq *)arg; musl_ifreq_tmp->ifr_ifru.ifru_hwaddr.sa_family = ARPHRD_LOOPBACK; } else { - struct musl_ifreq * musl_ifreq_tmp = (struct musl_ifreq *)arg; + struct musl_ifreq *musl_ifreq_tmp = (struct musl_ifreq *)arg; musl_ifreq_tmp->ifr_ifru.ifru_hwaddr.sa_family = ARPHRD_ETHER; } #endif @@ -1461,7 +1500,7 @@ int sal_ioctlsocket(int socket, long cmd, void *arg) ifconf_tmp->ifc_ifcu.ifcu_buf += sizeof(struct sal_ifreq); } ifconf_tmp->ifc_len = sizeof(struct sal_ifreq) * count_size; - ifconf_tmp->ifc_ifcu.ifcu_buf = ifconf_tmp->ifc_ifcu.ifcu_buf - sizeof(struct sal_ifreq) * count_size; + ifconf_tmp->ifc_ifcu.ifcu_buf = ifconf_tmp->ifc_ifcu.ifcu_buf - sizeof(struct sal_ifreq) * count_size; return 0; } case SIOCGIFINDEX: @@ -1556,7 +1595,7 @@ int sal_getaddrinfo(const char *nodename, { struct netdev *netdev = netdev_default; struct sal_proto_family *pf; - int ret = 0; + int ret = 0; rt_uint32_t i = 0; if (SAL_NETDEV_NETDBOPS_VALID(netdev, pf, getaddrinfo)) @@ -1577,12 +1616,12 @@ int sal_getaddrinfo(const char *nodename, } } - if(ret == RT_EOK) + if (ret == RT_EOK) { /*record the netdev and res*/ - for(i = 0; i < SAL_SOCKETS_NUM; i++) + for (i = 0; i < SAL_SOCKETS_NUM; i++) { - if(sal_dev_res_tbl[i].res == RT_NULL) + if (sal_dev_res_tbl[i].res == RT_NULL) { sal_dev_res_tbl[i].res = *res; sal_dev_res_tbl[i].netdev = netdev; @@ -1591,7 +1630,6 @@ int sal_getaddrinfo(const char *nodename, } RT_ASSERT((i < SAL_SOCKETS_NUM)); - } return ret; @@ -1601,12 +1639,12 @@ void sal_freeaddrinfo(struct addrinfo *ai) { struct netdev *netdev = RT_NULL; struct sal_proto_family *pf = RT_NULL; - rt_uint32_t i = 0; + rt_uint32_t i = 0; /*when use the multi netdev, it must free the ai use the getaddrinfo netdev */ - for(i = 0; i < SAL_SOCKETS_NUM; i++) + for (i = 0; i < SAL_SOCKETS_NUM; i++) { - if(sal_dev_res_tbl[i].res == ai) + if (sal_dev_res_tbl[i].res == ai) { netdev = sal_dev_res_tbl[i].netdev; sal_dev_res_tbl[i].res = RT_NULL;