1 /*
2  * Copyright (c) 2006-2023, RT-Thread Development Team
3  *
4  * SPDX-License-Identifier: Apache-2.0
5  *
6  * Change Logs:
7  * Date           Author       Notes
8  * 2018-05-23     ChenYong     First version
9  * 2018-11-12     ChenYong     Add TLS support
10  */
11 
12 #include <rtthread.h>
13 #include <rthw.h>
14 
15 #include <string.h>
16 #include <sys/time.h>
17 #include <sys/ioctl.h>
18 #include <unistd.h>
19 #include <fcntl.h>
20 
21 #include <sal_socket.h>
22 #include <sal_netdb.h>
23 #ifdef SAL_USING_TLS
24 #include <sal_tls.h>
25 #endif
26 #include <sal_low_lvl.h>
27 #include <netdev.h>
28 
29 #ifdef SAL_INTERNET_CHECK
30 #include <ipc/workqueue.h>
31 #endif
32 
33 #ifdef RT_USING_LWP
34 #include <lwp_sys_socket.h>
35 #endif
36 
37 /* check system workqueue stack size */
38 #if defined(SAL_INTERNET_CHECK) && RT_SYSTEM_WORKQUEUE_STACKSIZE < 1536
39 #error "The system workqueue stack size must more than 1536 bytes"
40 #endif
41 
42 #define DBG_TAG                        "sal.skt"
43 #define DBG_LVL                        DBG_INFO
44 #include <rtdbg.h>
45 
46 #define SOCKET_TABLE_STEP_LEN          4
47 
48 /* the socket table used to dynamic allocate sockets */
49 struct sal_socket_table
50 {
51     uint32_t max_socket;
52     struct sal_socket **sockets;
53 };
54 
55 /* record the netdev and res table*/
56 struct sal_netdev_res_table
57 {
58     struct addrinfo *res;
59     struct netdev *netdev;
60 };
61 
62 struct ifconf
63 {
64     int ifc_len;            /* Size of buffer.  */
65     union
66     {
67         char* ifcu_buf;
68         struct sal_ifreq *ifcu_req;
69     } ifc_ifcu;
70 };
71 
72 #ifdef SAL_USING_TLS
73 /* The global TLS protocol options */
74 static struct sal_proto_tls *proto_tls;
75 #endif
76 
77 /* The global socket table */
78 static struct sal_socket_table socket_table;
79 static struct rt_mutex sal_core_lock;
80 static rt_bool_t init_ok = RT_FALSE;
81 static struct sal_netdev_res_table sal_dev_res_tbl[SAL_SOCKETS_NUM];
82 
83 #define IS_SOCKET_PROTO_TLS(sock)                (((sock)->protocol == PROTOCOL_TLS) || \
84                                                  ((sock)->protocol == PROTOCOL_DTLS))
85 #define SAL_SOCKOPS_PROTO_TLS_VALID(sock, name)  (proto_tls && (proto_tls->ops->name) && IS_SOCKET_PROTO_TLS(sock))
86 
87 #define SAL_SOCKOPT_PROTO_TLS_EXEC(sock, name, optval, optlen)                    \
88 do {                                                                              \
89     if (SAL_SOCKOPS_PROTO_TLS_VALID(sock, name)){                                 \
90         return proto_tls->ops->name((sock)->user_data_tls, (optval), (optlen));   \
91     }                                                                             \
92 }while(0)                                                                         \
93 
94 #define SAL_SOCKET_OBJ_GET(sock, socket)                                          \
95 do {                                                                              \
96     (sock) = sal_get_socket(socket);                                              \
97     if ((sock) == RT_NULL) {                                                      \
98         return -1;                                                                \
99     }                                                                             \
100 }while(0)                                                                         \
101 
102 #define SAL_NETDEV_IS_UP(netdev)                                                  \
103 do {                                                                              \
104     if (!netdev_is_up(netdev)) {                                                  \
105         return -1;                                                                \
106     }                                                                             \
107 }while(0)                                                                         \
108 
109 #define SAL_NETDEV_SOCKETOPS_VALID(netdev, pf, ops)                               \
110 do {                                                                              \
111     (pf) = (struct sal_proto_family *) netdev->sal_user_data;                     \
112     if ((pf)->skt_ops->ops == RT_NULL){                                           \
113         return -1;                                                                \
114     }                                                                             \
115 }while(0)                                                                         \
116 
117 #define SAL_NETDEV_NETDBOPS_VALID(netdev, pf, ops)                                \
118     ((netdev) && netdev_is_up(netdev) &&                                          \
119     ((pf) = (struct sal_proto_family *) (netdev)->sal_user_data) != RT_NULL &&    \
120     (pf)->netdb_ops->ops)                                                         \
121 
122 #define SAL_NETDBOPS_VALID(netdev, pf, ops)                                \
123     ((netdev) &&                                                                 \
124     ((pf) = (struct sal_proto_family *) (netdev)->sal_user_data) != RT_NULL &&    \
125     (pf)->netdb_ops->ops)                                                         \
126 
127 /**
128  * SAL (Socket Abstraction Layer) initialize.
129  *
130  * @return result  0: initialize success
131  *                -1: initialize failed
132  */
sal_init(void)133 int sal_init(void)
134 {
135     int cn;
136 
137     if (init_ok)
138     {
139         LOG_D("Socket Abstraction Layer is already initialized.");
140         return 0;
141     }
142 
143     /* init sal socket table */
144     cn = SOCKET_TABLE_STEP_LEN < SAL_SOCKETS_NUM ? SOCKET_TABLE_STEP_LEN : SAL_SOCKETS_NUM;
145     socket_table.max_socket = cn;
146     socket_table.sockets = rt_calloc(1, cn * sizeof(struct sal_socket *));
147     if (socket_table.sockets == RT_NULL)
148     {
149         LOG_E("No memory for socket table.\n");
150         return -1;
151     }
152 
153     /*init the dev_res table */
154     rt_memset(sal_dev_res_tbl,  0, sizeof(sal_dev_res_tbl));
155 
156     /* create sal socket lock */
157     rt_mutex_init(&sal_core_lock, "sal_lock", RT_IPC_FLAG_PRIO);
158 
159     LOG_I("Socket Abstraction Layer initialize success.");
160     init_ok = RT_TRUE;
161 
162     return 0;
163 }
164 INIT_COMPONENT_EXPORT(sal_init);
165 
166 #ifdef SAL_INTERNET_CHECK
167 /* check SAL network interface device internet status */
check_netdev_internet_up_work(struct rt_work * work,void * work_data)168 static void check_netdev_internet_up_work(struct rt_work *work, void *work_data)
169 {
170 #define SAL_INTERNET_VERSION   0x00
171 #define SAL_INTERNET_BUFF_LEN  12
172 #define SAL_INTERNET_TIMEOUT   (2)
173 
174 #define SAL_INTERNET_HOST      "link.rt-thread.org"
175 #define SAL_INTERNET_PORT      8101
176 
177 #define SAL_INTERNET_MONTH_LEN 4
178 #define SAL_INTERNET_DATE_LEN  16
179 
180     unsigned int index;
181     int sockfd = -1, result = 0;
182     struct sockaddr_in server_addr;
183     struct hostent *host;
184     struct timeval timeout;
185     struct netdev *netdev = (struct netdev *)work_data;
186     socklen_t addr_len = sizeof(struct sockaddr_in);
187     char send_data[SAL_INTERNET_BUFF_LEN], recv_data = 0;
188 
189     const char month[][SAL_INTERNET_MONTH_LEN] = {"Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"};
190     char date[SAL_INTERNET_DATE_LEN];
191     unsigned int moth_num = 0;
192 
193     struct sal_proto_family *pf = (struct sal_proto_family *) netdev->sal_user_data;
194     const struct sal_socket_ops *skt_ops;
195 
196     if (work)
197     {
198         rt_free(work);
199     }
200 
201     /* get network interface socket operations */
202     if (pf == RT_NULL || pf->skt_ops == RT_NULL)
203     {
204         result = -RT_ERROR;
205         goto __exit;
206     }
207 
208     host = (struct hostent *) pf->netdb_ops->gethostbyname(SAL_INTERNET_HOST);
209     if (host == RT_NULL)
210     {
211         result = -RT_ERROR;
212         goto __exit;
213     }
214 
215     skt_ops = pf->skt_ops;
216     if ((sockfd = skt_ops->socket(AF_INET, SOCK_DGRAM, 0)) < 0)
217     {
218         result = -RT_ERROR;
219         goto __exit;
220     }
221 
222     server_addr.sin_family = AF_INET;
223     server_addr.sin_port = htons(SAL_INTERNET_PORT);
224     server_addr.sin_addr = *((struct in_addr *)host->h_addr);
225     rt_memset(&(server_addr.sin_zero), 0, sizeof(server_addr.sin_zero));
226 
227     timeout.tv_sec = SAL_INTERNET_TIMEOUT;
228     timeout.tv_usec = 0;
229 
230     /* set receive and send timeout */
231     skt_ops->setsockopt(sockfd, SOL_SOCKET, SO_RCVTIMEO, (void *) &timeout, sizeof(timeout));
232     skt_ops->setsockopt(sockfd, SOL_SOCKET, SO_SNDTIMEO, (void *) &timeout, sizeof(timeout));
233 
234     /* get build moth value*/
235     rt_memset(date, 0x00, SAL_INTERNET_DATE_LEN);
236     rt_snprintf(date, SAL_INTERNET_DATE_LEN, "%s", __DATE__);
237 
238     for (index = 0; index < sizeof(month) / SAL_INTERNET_MONTH_LEN; index++)
239     {
240         if (rt_memcmp(date, month[index], SAL_INTERNET_MONTH_LEN - 1) == 0)
241         {
242             moth_num = index + 1;
243             break;
244         }
245     }
246 
247     /* not find build month */
248     if (moth_num == 0 || moth_num > sizeof(month) / SAL_INTERNET_MONTH_LEN)
249     {
250         result = -RT_ERROR;
251         goto __exit;
252     }
253 
254     rt_memset(send_data, 0x00, SAL_INTERNET_BUFF_LEN);
255     send_data[0] = SAL_INTERNET_VERSION;
256     for (index = 0; index < netdev->hwaddr_len; index++)
257     {
258         send_data[index + 1] = netdev->hwaddr[index] + moth_num;
259     }
260     send_data[9] = RT_VERSION_MAJOR;
261     send_data[10] = RT_VERSION_MINOR;
262     send_data[11] = RT_VERSION_PATCH;
263 
264     skt_ops->sendto(sockfd, send_data, SAL_INTERNET_BUFF_LEN, 0,
265                     (struct sockaddr *)&server_addr, sizeof(struct sockaddr));
266 
267     result = skt_ops->recvfrom(sockfd, &recv_data, sizeof(recv_data), 0, (struct sockaddr *)&server_addr, &addr_len);
268     if (result < 0)
269     {
270         goto __exit;
271     }
272 
273     if (recv_data == RT_FALSE)
274     {
275         result = -RT_ERROR;
276         goto __exit;
277     }
278 
279 __exit:
280     if (result > 0)
281     {
282         LOG_D("Set network interface device(%s) internet status up.", netdev->name);
283         netdev_low_level_set_internet_status(netdev, RT_TRUE);
284     }
285     else
286     {
287         LOG_D("Set network interface device(%s) internet status down.", netdev->name);
288         netdev_low_level_set_internet_status(netdev, RT_FALSE);
289     }
290 
291     if (sockfd >= 0)
292     {
293         skt_ops->closesocket(sockfd);
294     }
295 }
296 #endif /* SAL_INTERNET_CHECK */
297 
298 /**
299  * This function will check SAL network interface device internet status.
300  *
301  * @param netdev the network interface device to check
302  */
sal_check_netdev_internet_up(struct netdev * netdev)303 int sal_check_netdev_internet_up(struct netdev *netdev)
304 {
305     RT_ASSERT(netdev);
306 
307 #ifdef SAL_INTERNET_CHECK
308     /* workqueue for network connect */
309     struct rt_work *net_work = RT_NULL;
310 
311 
312     net_work = (struct rt_work *)rt_calloc(1, sizeof(struct rt_work));
313     if (net_work == RT_NULL)
314     {
315         LOG_W("No memory for network interface device(%s) delay work.", netdev->name);
316         return -1;
317     }
318 
319     rt_work_init(net_work, check_netdev_internet_up_work, (void *)netdev);
320     rt_work_submit(net_work, RT_TICK_PER_SECOND);
321 #endif /* SAL_INTERNET_CHECK */
322     return 0;
323 }
324 
325 /**
326  * This function will register TLS protocol to the global TLS protocol.
327  *
328  * @param pt TLS protocol object
329  *
330  * @return 0: TLS protocol object register success
331  */
332 #ifdef SAL_USING_TLS
sal_proto_tls_register(const struct sal_proto_tls * pt)333 int sal_proto_tls_register(const struct sal_proto_tls *pt)
334 {
335     RT_ASSERT(pt);
336     proto_tls = (struct sal_proto_tls *) pt;
337 
338     return 0;
339 }
340 #endif
341 
342 /**
343  * This function will get sal socket object by sal socket descriptor.
344  *
345  * @param socket sal socket index
346  *
347  * @return sal socket object of the current sal socket index
348  */
sal_get_socket(int socket)349 struct sal_socket *sal_get_socket(int socket)
350 {
351     struct sal_socket_table *st = &socket_table;
352 
353     socket = socket - SAL_SOCKET_OFFSET;
354 
355     if (socket < 0 || socket >= (int) st->max_socket)
356     {
357         return RT_NULL;
358     }
359 
360     /* check socket structure valid or not */
361     RT_ASSERT(st->sockets[socket]->magic == SAL_SOCKET_MAGIC);
362 
363     return st->sockets[socket];
364 }
365 
366 /**
367  * This function will lock sal socket.
368  *
369  * @note please don't invoke it on ISR.
370  */
sal_lock(void)371 static void sal_lock(void)
372 {
373     rt_err_t result;
374 
375     result = rt_mutex_take(&sal_core_lock, RT_WAITING_FOREVER);
376     if (result != RT_EOK)
377     {
378         RT_ASSERT(0);
379     }
380 }
381 
382 /**
383  * This function will lock sal socket.
384  *
385  * @note please don't invoke it on ISR.
386  */
sal_unlock(void)387 static void sal_unlock(void)
388 {
389     rt_mutex_release(&sal_core_lock);
390 }
391 
392 /**
393  * This function will clean the netdev.
394  *
395  * @note please don't invoke it on ISR.
396  */
sal_netdev_cleanup(struct netdev * netdev)397 int sal_netdev_cleanup(struct netdev *netdev)
398 {
399     uint32_t idx = 0;
400     int find_dev;
401 
402     do
403     {
404         find_dev = 0;
405         sal_lock();
406         for (idx = 0; idx < socket_table.max_socket; idx++)
407         {
408             if (socket_table.sockets[idx] && socket_table.sockets[idx]->netdev == netdev)
409             {
410                 find_dev = 1;
411                 break;
412             }
413         }
414         sal_unlock();
415         if (find_dev)
416         {
417             rt_thread_mdelay(100);
418         }
419     }
420     while (find_dev);
421 
422     return 0;
423 }
424 
425 /**
426  * This function will initialize sal socket object and set socket options
427  *
428  * @param family    protocol family
429  * @param type      socket type
430  * @param protocol  transfer Protocol
431  * @param res       sal socket object address
432  *
433  * @return  0 : socket initialize success
434  *         -1 : input the wrong family
435  *         -2 : input the wrong socket type
436  *         -3 : get network interface failed
437  */
socket_init(int family,int type,int protocol,struct sal_socket ** res)438 static int socket_init(int family, int type, int protocol, struct sal_socket **res)
439 {
440 
441     struct sal_socket *sock;
442     struct sal_proto_family *pf;
443     struct netdev *netdv_def = netdev_default;
444     struct netdev *netdev = RT_NULL;
445     rt_bool_t flag = RT_FALSE;
446 
447     if (family < 0 || family > AF_MAX)
448     {
449         return -1;
450     }
451 
452     if (type < 0 || type > SOCK_MAX)
453     {
454         return -2;
455     }
456 
457     sock = *res;
458     sock->domain = family;
459     sock->type = type;
460     sock->protocol = protocol;
461 
462     if (netdv_def && netdev_is_up(netdv_def))
463     {
464         /* check default network interface device protocol family */
465         pf = (struct sal_proto_family *) netdv_def->sal_user_data;
466         if (pf != RT_NULL && pf->skt_ops && (pf->family == family || pf->sec_family == family))
467         {
468             sock->netdev = netdv_def;
469             flag = RT_TRUE;
470         }
471     }
472 
473     if (flag == RT_FALSE)
474     {
475         /* get network interface device by protocol family */
476         netdev = netdev_get_by_family(family);
477         if (netdev == RT_NULL)
478         {
479             LOG_E("not find network interface device by protocol family(%d).", family);
480             return -3;
481         }
482 
483         sock->netdev = netdev;
484     }
485 
486     return 0;
487 }
488 
socket_alloc(struct sal_socket_table * st,int f_socket)489 static int socket_alloc(struct sal_socket_table *st, int f_socket)
490 {
491     int idx;
492 
493     /* find an empty socket entry */
494     for (idx = f_socket; idx < (int) st->max_socket; idx++)
495     {
496         if (st->sockets[idx] == RT_NULL)
497         {
498             break;
499         }
500     }
501 
502     /* allocate a larger sockte container */
503     if (idx == (int) st->max_socket &&  st->max_socket < SAL_SOCKETS_NUM)
504     {
505         int cnt, index;
506         struct sal_socket **sockets;
507 
508         /* increase the number of socket with 4 step length */
509         cnt = st->max_socket + SOCKET_TABLE_STEP_LEN;
510         cnt = cnt > SAL_SOCKETS_NUM ? SAL_SOCKETS_NUM : cnt;
511 
512         sockets = rt_realloc(st->sockets, cnt * sizeof(struct sal_socket *));
513         if (sockets == RT_NULL)
514             goto __result; /* return st->max_socket */
515 
516         /* clean the new allocated fds */
517         for (index = st->max_socket; index < cnt; index++)
518         {
519             sockets[index] = RT_NULL;
520         }
521 
522         st->sockets = sockets;
523         st->max_socket = cnt;
524     }
525 
526     /* allocate  'struct sal_socket' */
527     if (idx < (int) st->max_socket && st->sockets[idx] == RT_NULL)
528     {
529         st->sockets[idx] = rt_calloc(1, sizeof(struct sal_socket));
530         if (st->sockets[idx] == RT_NULL)
531         {
532             idx = st->max_socket;
533         }
534     }
535 
536 __result:
537     return idx;
538 }
539 
socket_free(struct sal_socket_table * st,int idx)540 static void socket_free(struct sal_socket_table *st, int idx)
541 {
542     struct sal_socket *sock;
543 
544     sock = st->sockets[idx];
545     st->sockets[idx] = RT_NULL;
546     rt_free(sock);
547 }
548 
socket_new(void)549 static int socket_new(void)
550 {
551     struct sal_socket *sock;
552     struct sal_socket_table *st = &socket_table;
553     int idx;
554 
555     sal_lock();
556 
557     /* find an empty sal socket entry */
558     idx = socket_alloc(st, 0);
559 
560     /* can't find an empty sal socket entry */
561     if (idx == (int) st->max_socket)
562     {
563         idx = -(1 + SAL_SOCKET_OFFSET);
564         goto __result;
565     }
566 
567     sock = st->sockets[idx];
568     sock->socket = idx + SAL_SOCKET_OFFSET;
569     sock->magic = SAL_SOCKET_MAGIC;
570     sock->netdev = RT_NULL;
571     sock->user_data = RT_NULL;
572 #ifdef SAL_USING_TLS
573     sock->user_data_tls = RT_NULL;
574 #endif
575 
576 __result:
577     sal_unlock();
578     return idx + SAL_SOCKET_OFFSET;
579 }
580 
socket_delete(int socket)581 static void socket_delete(int socket)
582 {
583     struct sal_socket *sock;
584     struct sal_socket_table *st = &socket_table;
585     int idx;
586 
587     idx = socket - SAL_SOCKET_OFFSET;
588     if (idx < 0 || idx >= (int) st->max_socket)
589     {
590         return;
591     }
592     sal_lock();
593     sock = sal_get_socket(socket);
594     RT_ASSERT(sock != RT_NULL);
595     sock->magic = 0;
596     sock->netdev = RT_NULL;
597     socket_free(st, idx);
598     sal_unlock();
599 }
600 
sal_accept(int socket,struct sockaddr * addr,socklen_t * addrlen)601 int sal_accept(int socket, struct sockaddr *addr, socklen_t *addrlen)
602 {
603     int new_socket;
604     struct sal_socket *sock;
605     struct sal_proto_family *pf;
606 
607     /* get the socket object by socket descriptor */
608     SAL_SOCKET_OBJ_GET(sock, socket);
609 
610     /* check the network interface is up status */
611     SAL_NETDEV_IS_UP(sock->netdev);
612 
613     /* check the network interface socket operations */
614     SAL_NETDEV_SOCKETOPS_VALID(sock->netdev, pf, accept);
615 
616     new_socket = pf->skt_ops->accept((int)(size_t)sock->user_data, addr, addrlen);
617     if (new_socket != -1)
618     {
619         int retval;
620         int new_sal_socket;
621         struct sal_socket *new_sock;
622 
623         /* allocate a new socket structure and registered socket options */
624         new_sal_socket = socket_new();
625         new_sock = sal_get_socket(new_sal_socket);
626         if (new_sock == RT_NULL)
627         {
628             pf->skt_ops->closesocket(new_socket);
629             return -1;
630         }
631 
632         retval = socket_init(sock->domain, sock->type, sock->protocol, &new_sock);
633         if (retval < 0)
634         {
635             pf->skt_ops->closesocket(new_socket);
636             rt_memset(new_sock, 0x00, sizeof(struct sal_socket));
637             /* socket init failed, delete socket */
638             socket_delete(new_sal_socket);
639             LOG_E("New socket registered failed, return error %d.", retval);
640             return -1;
641         }
642 
643         /* new socket create by accept should have the same netdev with server*/
644         new_sock->netdev = sock->netdev;
645         /* socket structure user_data used to store the acquired new socket */
646         new_sock->user_data = (void *)(size_t)new_socket;
647 
648         return new_sal_socket;
649     }
650 
651     return -1;
652 }
653 
sal_sockaddr_to_ipaddr(const struct sockaddr * name,ip_addr_t * local_ipaddr)654 static void sal_sockaddr_to_ipaddr(const struct sockaddr *name, ip_addr_t *local_ipaddr)
655 {
656     const struct sockaddr_in *svr_addr = (const struct sockaddr_in *) name;
657 
658 #if NETDEV_IPV4 && NETDEV_IPV6
659     local_ipaddr->u_addr.ip4.addr = svr_addr->sin_addr.s_addr;
660     local_ipaddr->type = IPADDR_TYPE_V4;
661 #elif NETDEV_IPV4
662     local_ipaddr->addr = svr_addr->sin_addr.s_addr;
663 #elif NETDEV_IPV6
664 #error "not only support IPV6"
665 #endif /* NETDEV_IPV4 && NETDEV_IPV6*/
666 }
667 
sal_bind(int socket,const struct sockaddr * name,socklen_t namelen)668 int sal_bind(int socket, const struct sockaddr *name, socklen_t namelen)
669 {
670     struct sal_socket *sock;
671     struct sal_proto_family *pf;
672     struct sockaddr_un *addr_un = RT_NULL;
673     ip_addr_t input_ipaddr;
674 
675     RT_ASSERT(name);
676 
677     /* get the socket object by socket descriptor */
678     SAL_SOCKET_OBJ_GET(sock, socket);
679 
680     addr_un = (struct sockaddr_un *)name;
681 
682 #define IS_INET_ADDR_FAMILY(_af) ((_af) == AF_INET) || ((_af) == AF_INET6)
683     if (IS_INET_ADDR_FAMILY(name->sa_family))
684     {
685         /* bind network interface by ip address */
686         sal_sockaddr_to_ipaddr(name, &input_ipaddr);
687 
688         /* check input ipaddr is default netdev ipaddr */
689         if (!ip_addr_isany_val(input_ipaddr))
690         {
691             struct sal_proto_family *input_pf = RT_NULL, *local_pf = RT_NULL;
692             struct netdev *new_netdev = RT_NULL;
693 
694             new_netdev = netdev_get_by_ipaddr(&input_ipaddr);
695             if (new_netdev == RT_NULL)
696             {
697                 return -1;
698             }
699 
700             /* get input and local ip address proto_family */
701             SAL_NETDEV_SOCKETOPS_VALID(sock->netdev, local_pf, bind);
702             SAL_NETDEV_SOCKETOPS_VALID(new_netdev, input_pf, bind);
703 
704             /* check the network interface protocol family type */
705             if (input_pf->family != local_pf->family)
706             {
707                 int new_socket = -1;
708 
709                 /* protocol family is different, close old socket and create new socket by input ip address */
710                 local_pf->skt_ops->closesocket(socket);
711 
712                 new_socket = input_pf->skt_ops->socket(input_pf->family, sock->type, sock->protocol);
713                 if (new_socket < 0)
714                 {
715                     return -1;
716                 }
717                 sock->netdev = new_netdev;
718                 sock->user_data = (void *)(size_t)new_socket;
719             }
720         }
721     }
722     /* check and get protocol families by the network interface device */
723     SAL_NETDEV_SOCKETOPS_VALID(sock->netdev, pf, bind);
724     return pf->skt_ops->bind((int)(size_t)sock->user_data, name, namelen);
725 }
726 
sal_shutdown(int socket,int how)727 int sal_shutdown(int socket, int how)
728 {
729     struct sal_socket *sock;
730     struct sal_proto_family *pf;
731     int error = 0;
732 
733     /* get the socket object by socket descriptor */
734     SAL_SOCKET_OBJ_GET(sock, socket);
735 
736     /* shutdown operation not need to check network interface status */
737     /* check the network interface socket opreation */
738     SAL_NETDEV_SOCKETOPS_VALID(sock->netdev, pf, shutdown);
739 
740     if (pf->skt_ops->shutdown((int)(size_t)sock->user_data, how) == 0)
741     {
742 #ifdef SAL_USING_TLS
743         if (SAL_SOCKOPS_PROTO_TLS_VALID(sock, closesocket))
744         {
745             if (proto_tls->ops->closesocket(sock->user_data_tls) < 0)
746             {
747                 return -1;
748             }
749         }
750 #endif
751         error = 0;
752     }
753     else
754     {
755         error = -1;
756     }
757 
758 
759     return error;
760 }
761 
sal_getpeername(int socket,struct sockaddr * name,socklen_t * namelen)762 int sal_getpeername(int socket, struct sockaddr *name, socklen_t *namelen)
763 {
764     struct sal_socket *sock;
765     struct sal_proto_family *pf;
766 
767     /* get the socket object by socket descriptor */
768     SAL_SOCKET_OBJ_GET(sock, socket);
769 
770     /* check the network interface socket opreation */
771     SAL_NETDEV_SOCKETOPS_VALID(sock->netdev, pf, getpeername);
772 
773     return pf->skt_ops->getpeername((int)(size_t)sock->user_data, name, namelen);
774 }
775 
sal_getsockname(int socket,struct sockaddr * name,socklen_t * namelen)776 int sal_getsockname(int socket, struct sockaddr *name, socklen_t *namelen)
777 {
778     struct sal_socket *sock;
779     struct sal_proto_family *pf;
780 
781     /* get socket object by socket descriptor */
782     SAL_SOCKET_OBJ_GET(sock, socket);
783 
784     /* check the network interface socket opreation */
785     SAL_NETDEV_SOCKETOPS_VALID(sock->netdev, pf, getsockname);
786 
787     return pf->skt_ops->getsockname((int)(size_t)sock->user_data, name, namelen);
788 }
789 
sal_getsockopt(int socket,int level,int optname,void * optval,socklen_t * optlen)790 int sal_getsockopt(int socket, int level, int optname, void *optval, socklen_t *optlen)
791 {
792     struct sal_socket *sock;
793     struct sal_proto_family *pf;
794 
795     /* get the socket object by socket descriptor */
796     SAL_SOCKET_OBJ_GET(sock, socket);
797 
798     /* check the network interface socket opreation */
799     SAL_NETDEV_SOCKETOPS_VALID(sock->netdev, pf, getsockopt);
800 
801     return pf->skt_ops->getsockopt((int)(size_t)sock->user_data, level, optname, optval, optlen);
802 }
803 
sal_setsockopt(int socket,int level,int optname,const void * optval,socklen_t optlen)804 int sal_setsockopt(int socket, int level, int optname, const void *optval, socklen_t optlen)
805 {
806     struct sal_socket *sock;
807     struct sal_proto_family *pf;
808 
809     /* get the socket object by socket descriptor */
810     SAL_SOCKET_OBJ_GET(sock, socket);
811 
812     /* check the network interface socket opreation */
813     SAL_NETDEV_SOCKETOPS_VALID(sock->netdev, pf, setsockopt);
814 
815 #ifdef SAL_USING_TLS
816     if (level == SOL_TLS)
817     {
818         switch (optname)
819         {
820         case TLS_CRET_LIST:
821             SAL_SOCKOPT_PROTO_TLS_EXEC(sock, set_cret_list, optval, optlen);
822             break;
823 
824         case TLS_CIPHERSUITE_LIST:
825             SAL_SOCKOPT_PROTO_TLS_EXEC(sock, set_ciphersurite, optval, optlen);
826             break;
827 
828         case TLS_PEER_VERIFY:
829             SAL_SOCKOPT_PROTO_TLS_EXEC(sock, set_peer_verify, optval, optlen);
830             break;
831 
832         case TLS_DTLS_ROLE:
833             SAL_SOCKOPT_PROTO_TLS_EXEC(sock, set_dtls_role, optval, optlen);
834             break;
835 
836         default:
837             return -1;
838         }
839 
840         return 0;
841     }
842     else
843     {
844         return pf->skt_ops->setsockopt((int) sock->user_data, level, optname, optval, optlen);
845     }
846 #else
847     return pf->skt_ops->setsockopt((int)(size_t)sock->user_data, level, optname, optval, optlen);
848 #endif /* SAL_USING_TLS */
849 }
850 
sal_connect(int socket,const struct sockaddr * name,socklen_t namelen)851 int sal_connect(int socket, const struct sockaddr *name, socklen_t namelen)
852 {
853     struct sal_socket *sock;
854     struct sal_proto_family *pf;
855     int ret;
856 
857     /* get the socket object by socket descriptor */
858     SAL_SOCKET_OBJ_GET(sock, socket);
859 
860     /* check the network interface is up status */
861     SAL_NETDEV_IS_UP(sock->netdev);
862     /* check the network interface socket opreation */
863     SAL_NETDEV_SOCKETOPS_VALID(sock->netdev, pf, connect);
864 
865     ret = pf->skt_ops->connect((int)(size_t)sock->user_data, name, namelen);
866 #ifdef SAL_USING_TLS
867     if (ret >= 0 && SAL_SOCKOPS_PROTO_TLS_VALID(sock, connect))
868     {
869         if (proto_tls->ops->connect(sock->user_data_tls) < 0)
870         {
871             return -1;
872         }
873 
874         return ret;
875     }
876 #endif
877 
878     return ret;
879 }
880 
sal_listen(int socket,int backlog)881 int sal_listen(int socket, int backlog)
882 {
883     struct sal_socket *sock;
884     struct sal_proto_family *pf;
885 
886     /* get the socket object by socket descriptor */
887     SAL_SOCKET_OBJ_GET(sock, socket);
888 
889     /* check the network interface socket opreation */
890     SAL_NETDEV_SOCKETOPS_VALID(sock->netdev, pf, listen);
891 
892     return pf->skt_ops->listen((int)(size_t)sock->user_data, backlog);
893 }
894 
sal_sendmsg(int socket,const struct msghdr * message,int flags)895 int sal_sendmsg(int socket, const struct msghdr *message, int flags)
896 {
897     struct sal_socket *sock;
898     struct sal_proto_family *pf;
899 
900     /* get the socket object by socket descriptor */
901     SAL_SOCKET_OBJ_GET(sock, socket);
902 
903     /* check the network interface is up status  */
904     SAL_NETDEV_IS_UP(sock->netdev);
905     /* check the network interface socket opreation */
906     SAL_NETDEV_SOCKETOPS_VALID(sock->netdev, pf, sendmsg);
907 
908 #ifdef SAL_USING_TLS
909     if (SAL_SOCKOPS_PROTO_TLS_VALID(sock, send))
910     {
911         int ret;
912 
913         if ((ret = proto_tls->ops->send(sock->user_data_tls, message, flags)) < 0)
914         {
915             return -1;
916         }
917         return ret;
918     }
919     else
920     {
921         return pf->skt_ops->sendmsg((int)(size_t)sock->user_data, message, flags);
922     }
923 #else
924     return pf->skt_ops->sendmsg((int)(size_t)sock->user_data, message, flags);
925 #endif
926 }
927 
sal_recvmsg(int socket,struct msghdr * message,int flags)928 int sal_recvmsg(int socket, struct msghdr *message, int flags)
929 {
930     struct sal_socket *sock;
931     struct sal_proto_family *pf;
932 
933     /* get the socket object by socket descriptor */
934     SAL_SOCKET_OBJ_GET(sock, socket);
935 
936     /* check the network interface is up status  */
937     SAL_NETDEV_IS_UP(sock->netdev);
938     /* check the network interface socket opreation */
939     SAL_NETDEV_SOCKETOPS_VALID(sock->netdev, pf, recvmsg);
940 
941 #ifdef SAL_USING_TLS
942     if (SAL_SOCKOPS_PROTO_TLS_VALID(sock, recv))
943     {
944         int ret;
945 
946         if ((ret = proto_tls->ops->recv(sock->user_data_tls, message, flags)) < 0)
947         {
948             return -1;
949         }
950         return ret;
951     }
952     else
953     {
954         return pf->skt_ops->recvmsg((int)(size_t)sock->user_data, message, flags);
955     }
956 #else
957     return pf->skt_ops->recvmsg((int)(size_t)sock->user_data, message, flags);
958 #endif
959 }
960 
sal_recvfrom(int socket,void * mem,size_t len,int flags,struct sockaddr * from,socklen_t * fromlen)961 int sal_recvfrom(int socket, void *mem, size_t len, int flags,
962                  struct sockaddr *from, socklen_t *fromlen)
963 {
964     struct sal_socket *sock;
965     struct sal_proto_family *pf;
966 
967     /* get the socket object by socket descriptor */
968     SAL_SOCKET_OBJ_GET(sock, socket);
969 
970     /* check the network interface is up status  */
971     SAL_NETDEV_IS_UP(sock->netdev);
972     /* check the network interface socket opreation */
973     SAL_NETDEV_SOCKETOPS_VALID(sock->netdev, pf, recvfrom);
974 
975 #ifdef SAL_USING_TLS
976     if (SAL_SOCKOPS_PROTO_TLS_VALID(sock, recv))
977     {
978         int ret;
979 
980         if ((ret = proto_tls->ops->recv(sock->user_data_tls, mem, len)) < 0)
981         {
982             return -1;
983         }
984         return ret;
985     }
986     else
987     {
988         return pf->skt_ops->recvfrom((int)(size_t)sock->user_data, mem, len, flags, from, fromlen);
989     }
990 #else
991     return pf->skt_ops->recvfrom((int)(size_t)sock->user_data, mem, len, flags, from, fromlen);
992 #endif
993 }
994 
sal_sendto(int socket,const void * dataptr,size_t size,int flags,const struct sockaddr * to,socklen_t tolen)995 int sal_sendto(int socket, const void *dataptr, size_t size, int flags,
996                const struct sockaddr *to, socklen_t tolen)
997 {
998     struct sal_socket *sock;
999     struct sal_proto_family *pf;
1000 
1001     /* get the socket object by socket descriptor */
1002     SAL_SOCKET_OBJ_GET(sock, socket);
1003 
1004     /* check the network interface is up status  */
1005     SAL_NETDEV_IS_UP(sock->netdev);
1006     /* check the network interface socket opreation */
1007     SAL_NETDEV_SOCKETOPS_VALID(sock->netdev, pf, sendto);
1008 
1009 #ifdef SAL_USING_TLS
1010     if (SAL_SOCKOPS_PROTO_TLS_VALID(sock, send))
1011     {
1012         int ret;
1013 
1014         if ((ret = proto_tls->ops->send(sock->user_data_tls, dataptr, size)) < 0)
1015         {
1016             return -1;
1017         }
1018         return ret;
1019     }
1020     else
1021     {
1022         return pf->skt_ops->sendto((int) sock->user_data, dataptr, size, flags, to, tolen);
1023     }
1024 #else
1025     return pf->skt_ops->sendto((int)(size_t)sock->user_data, dataptr, size, flags, to, tolen);
1026 #endif
1027 }
1028 
sal_socket(int domain,int type,int protocol)1029 int sal_socket(int domain, int type, int protocol)
1030 {
1031     int retval;
1032     int socket, proto_socket;
1033     struct sal_socket *sock;
1034     struct sal_proto_family *pf;
1035 
1036     /* allocate a new socket and registered socket options */
1037     socket = socket_new();
1038     if (socket < 0)
1039     {
1040         return -1;
1041     }
1042 
1043     /* get sal socket object by socket descriptor */
1044     sock = sal_get_socket(socket);
1045     if (sock == RT_NULL)
1046     {
1047         socket_delete(socket);
1048         return -1;
1049     }
1050 
1051     /* Initialize sal socket object */
1052     retval = socket_init(domain, type, protocol, &sock);
1053     if (retval < 0)
1054     {
1055         LOG_E("SAL socket protocol family input failed, return error %d.", retval);
1056         socket_delete(socket);
1057         return -1;
1058     }
1059 
1060     /* valid the network interface socket opreation */
1061     SAL_NETDEV_SOCKETOPS_VALID(sock->netdev, pf, socket);
1062 
1063     proto_socket = pf->skt_ops->socket(domain, type, protocol);
1064     if (proto_socket >= 0)
1065     {
1066 #ifdef SAL_USING_TLS
1067         if (SAL_SOCKOPS_PROTO_TLS_VALID(sock, socket))
1068         {
1069             sock->user_data_tls = proto_tls->ops->socket(socket);
1070             if (sock->user_data_tls == RT_NULL)
1071             {
1072                 socket_delete(socket);
1073                 return -1;
1074             }
1075         }
1076 #endif
1077         sock->user_data = (void *)(size_t)proto_socket;
1078         return sock->socket;
1079     }
1080     socket_delete(socket);
1081     return -1;
1082 }
1083 
sal_socketpair(int domain,int type,int protocol,int * fds)1084 int sal_socketpair(int domain, int type, int protocol, int *fds)
1085 {
1086     int unix_fd[2];
1087     struct sal_socket *socka;
1088     struct sal_socket *sockb;
1089     struct sal_proto_family *pf;
1090 
1091     if (domain == AF_UNIX)
1092     {
1093         /* get the socket object by socket descriptor */
1094         SAL_SOCKET_OBJ_GET(socka, fds[0]);
1095         SAL_SOCKET_OBJ_GET(sockb, fds[1]);
1096 
1097         /* valid the network interface socket opreation */
1098         SAL_NETDEV_SOCKETOPS_VALID(socka->netdev, pf, socket);
1099 
1100         unix_fd[0] = (int)(size_t)socka->user_data;
1101         unix_fd[1] = (int)(size_t)sockb->user_data;
1102 
1103         if (pf->skt_ops->socketpair)
1104         {
1105             return pf->skt_ops->socketpair(domain, type, protocol, unix_fd);
1106         }
1107     }
1108 
1109     rt_set_errno(EINVAL);
1110 
1111     return -1;
1112 }
1113 
sal_closesocket(int socket)1114 int sal_closesocket(int socket)
1115 {
1116     struct sal_socket *sock;
1117     struct sal_proto_family *pf;
1118     int error = 0;
1119 
1120     /* get the socket object by socket descriptor */
1121     SAL_SOCKET_OBJ_GET(sock, socket);
1122 
1123     /* clsoesocket operation not need to vaild network interface status */
1124     /* valid the network interface socket opreation */
1125     SAL_NETDEV_SOCKETOPS_VALID(sock->netdev, pf, closesocket);
1126 
1127     if (pf->skt_ops->closesocket((int)(size_t)sock->user_data) == 0)
1128     {
1129 #ifdef SAL_USING_TLS
1130         if (SAL_SOCKOPS_PROTO_TLS_VALID(sock, closesocket))
1131         {
1132             if (proto_tls->ops->closesocket(sock->user_data_tls) < 0)
1133             {
1134                 return -1;
1135             }
1136         }
1137 #endif
1138         error = 0;
1139     }
1140     else
1141     {
1142         error = -1;
1143     }
1144 
1145     /* delete socket */
1146     socket_delete(socket);
1147 
1148     return error;
1149 }
1150 
1151 #define ARPHRD_ETHER    1      /* Ethernet 10/100Mbps. */
1152 #define ARPHRD_LOOPBACK 772    /* Loopback device.  */
1153 #define IFF_UP  0x1
1154 #define IFF_RUNNING 0x40
1155 #define IFF_NOARP 0x80
1156 
sal_ioctlsocket(int socket,long cmd,void * arg)1157 int sal_ioctlsocket(int socket, long cmd, void *arg)
1158 {
1159     rt_slist_t *node  = RT_NULL;
1160     struct netdev *netdev = RT_NULL;
1161     struct netdev *cur_netdev_list = netdev_list;
1162     struct sal_socket *sock;
1163     struct sal_proto_family *pf;
1164     struct sockaddr_in *addr_in = RT_NULL;
1165     struct sockaddr *addr = RT_NULL;
1166     ip_addr_t input_ipaddr;
1167     /* get the socket object by socket descriptor */
1168     SAL_SOCKET_OBJ_GET(sock, socket);
1169 
1170     struct sal_ifreq *ifr = (struct sal_ifreq *)arg;
1171 
1172     if (ifr != RT_NULL)
1173     {
1174         switch (cmd)
1175         {
1176         case SIOCGIFADDR:
1177             if (!strcmp(ifr->ifr_ifrn.ifrn_name, sock->netdev->name))
1178             {
1179                 addr_in = (struct sockaddr_in *)&(ifr->ifr_ifru.ifru_addr);
1180             #if NETDEV_IPV4 && NETDEV_IPV6
1181                 addr_in->sin_addr.s_addr = sock->netdev->ip_addr.u_addr.ip4.addr;
1182             #elif NETDEV_IPV4
1183                 addr_in->sin_addr.s_addr = sock->netdev->ip_addr.addr;
1184             #elif NETDEV_IPV6
1185             #error "not only support IPV6"
1186             #endif /* NETDEV_IPV4 && NETDEV_IPV6*/
1187                 return 0;
1188             }
1189             else
1190             {
1191                 if (cur_netdev_list == RT_NULL)
1192                 {
1193                     LOG_E("ifconfig: network interface device list error.\n");
1194                     return -1;
1195                 }
1196 
1197                 for (node = &(cur_netdev_list->list); node; node = rt_slist_next(node))
1198                 {
1199                     netdev = rt_list_entry(node, struct netdev, list);
1200                     if (!strcmp(ifr->ifr_ifrn.ifrn_name, netdev->name))
1201                     {
1202                         addr_in = (struct sockaddr_in *)&(ifr->ifr_ifru.ifru_addr);
1203                     #if NETDEV_IPV4 && NETDEV_IPV6
1204                         addr_in->sin_addr.s_addr = netdev->ip_addr.u_addr.ip4.addr;
1205                     #elif NETDEV_IPV4
1206                         addr_in->sin_addr.s_addr = netdev->ip_addr.addr;
1207                     #elif NETDEV_IPV6
1208                     #error "Do not only support IPV6"
1209                     #endif /* NETDEV_IPV4 && NETDEV_IPV6 */
1210 
1211                         return 0;
1212                     }
1213                 }
1214                 return -1;
1215             }
1216 
1217         case SIOCSIFADDR:
1218             if (!strcmp(ifr->ifr_ifrn.ifrn_name, sock->netdev->name))
1219             {
1220                 addr = (struct sockaddr *)&(ifr->ifr_ifru.ifru_addr);
1221                 sal_sockaddr_to_ipaddr(addr, &input_ipaddr);
1222                 netdev_set_ipaddr(sock->netdev, &input_ipaddr);
1223                 return 0;
1224             }
1225             else
1226             {
1227                 if (cur_netdev_list == RT_NULL)
1228                 {
1229                     LOG_E("ifconfig: network interface device list error.\n");
1230                     return -1;
1231                 }
1232 
1233                 for (node = &(cur_netdev_list->list); node; node = rt_slist_next(node))
1234                 {
1235                     netdev = rt_list_entry(node, struct netdev, list);
1236                     if (!strcmp(ifr->ifr_ifrn.ifrn_name, netdev->name))
1237                     {
1238                         addr = (struct sockaddr *)&(ifr->ifr_ifru.ifru_addr);
1239                         sal_sockaddr_to_ipaddr(addr, &input_ipaddr);
1240                         netdev_set_ipaddr(netdev, &input_ipaddr);
1241                         return 0;
1242                     }
1243                 }
1244                 return -1;
1245             }
1246 
1247         case SIOCGIFNETMASK:
1248             if (!strcmp(ifr->ifr_ifrn.ifrn_name, sock->netdev->name))
1249             {
1250                 addr_in = (struct sockaddr_in *)&(ifr->ifr_ifru.ifru_netmask);
1251             #if NETDEV_IPV4 && NETDEV_IPV6
1252                 addr_in->sin_addr.s_addr = sock->netdev->netmask.u_addr.ip4.addr;
1253             #elif NETDEV_IPV4
1254                 addr_in->sin_addr.s_addr = sock->netdev->netmask.addr;
1255             #elif NETDEV_IPV6
1256             #error "not only support IPV6"
1257             #endif /* NETDEV_IPV4 && NETDEV_IPV6*/
1258                 return 0;
1259             }
1260             else
1261             {
1262                 if (cur_netdev_list == RT_NULL)
1263                 {
1264                     LOG_E("ifconfig: network interface device list error.\n");
1265                     return -1;
1266                 }
1267 
1268                 for (node = &(cur_netdev_list->list); node; node = rt_slist_next(node))
1269                 {
1270                     netdev = rt_list_entry(node, struct netdev, list);
1271                     if (!strcmp(ifr->ifr_ifrn.ifrn_name, netdev->name))
1272                     {
1273                         addr_in = (struct sockaddr_in *)&(ifr->ifr_ifru.ifru_netmask);
1274                     #if NETDEV_IPV4 && NETDEV_IPV6
1275                         addr_in->sin_addr.s_addr = netdev->netmask.u_addr.ip4.addr;
1276                     #elif NETDEV_IPV4
1277                         addr_in->sin_addr.s_addr = netdev->netmask.addr;
1278                     #elif NETDEV_IPV6
1279                     #error "not only support IPV6"
1280                     #endif /* NETDEV_IPV4 && NETDEV_IPV6*/
1281                         return 0;
1282                     }
1283                 }
1284                 return -1;
1285             }
1286 
1287         case SIOCSIFNETMASK:
1288             if (!strcmp(ifr->ifr_ifrn.ifrn_name, sock->netdev->name))
1289             {
1290                 addr = (struct sockaddr *)&(ifr->ifr_ifru.ifru_netmask);
1291                 sal_sockaddr_to_ipaddr(addr, &input_ipaddr);
1292                 netdev_set_netmask(sock->netdev, &input_ipaddr);
1293                 return 0;
1294             }
1295             else
1296             {
1297                 if (cur_netdev_list == RT_NULL)
1298                 {
1299                     LOG_E("ifconfig: network interface device list error.\n");
1300                     return -1;
1301                 }
1302 
1303                 for (node = &(cur_netdev_list->list); node; node = rt_slist_next(node))
1304                 {
1305                     netdev = rt_list_entry(node, struct netdev, list);
1306                     if (!strcmp(ifr->ifr_ifrn.ifrn_name, netdev->name))
1307                     {
1308                         addr = (struct sockaddr *)&(ifr->ifr_ifru.ifru_netmask);
1309                         sal_sockaddr_to_ipaddr(addr, &input_ipaddr);
1310                         netdev_set_netmask(netdev, &input_ipaddr);
1311                         return 0;
1312                     }
1313                 }
1314                 return -1;
1315             }
1316 
1317         case SIOCGIFHWADDR:
1318             if (!strcmp(ifr->ifr_ifrn.ifrn_name,sock->netdev->name))
1319             {
1320                 addr = (struct sockaddr *)&(ifr->ifr_ifru.ifru_hwaddr);
1321 #ifdef RT_USING_LWP
1322                 if (!strcmp("lo", sock->netdev->name))
1323                 {
1324                     struct musl_ifreq * musl_ifreq_tmp = (struct musl_ifreq *)arg;
1325                     musl_ifreq_tmp->ifr_ifru.ifru_hwaddr.sa_family = ARPHRD_LOOPBACK;
1326                 }
1327                 else
1328                 {
1329                     struct musl_ifreq * musl_ifreq_tmp = (struct musl_ifreq *)arg;
1330                     musl_ifreq_tmp->ifr_ifru.ifru_hwaddr.sa_family = ARPHRD_ETHER;
1331                 }
1332 #endif
1333                 rt_memcpy(addr->sa_data, sock->netdev->hwaddr, sock->netdev->hwaddr_len);
1334                 return 0;
1335             }
1336             else
1337             {
1338                 if (cur_netdev_list == RT_NULL)
1339                 {
1340                     LOG_E("ifconfig: network interface device list error.\n");
1341                     return -1;
1342                 }
1343 
1344                 for (node = &(cur_netdev_list->list); node; node = rt_slist_next(node))
1345                 {
1346                     netdev = rt_list_entry(node, struct netdev, list);
1347                     if (!strcmp(ifr->ifr_ifrn.ifrn_name, netdev->name))
1348                     {
1349                         addr = (struct sockaddr *)&(ifr->ifr_ifru.ifru_hwaddr);
1350 #ifdef RT_USING_LWP
1351                         if (!strcmp("lo", netdev->name))
1352                         {
1353                             struct musl_ifreq * musl_ifreq_tmp = (struct musl_ifreq *)arg;
1354                             musl_ifreq_tmp->ifr_ifru.ifru_hwaddr.sa_family = ARPHRD_LOOPBACK;
1355                         }
1356                         else
1357                         {
1358                             struct musl_ifreq * musl_ifreq_tmp = (struct musl_ifreq *)arg;
1359                             musl_ifreq_tmp->ifr_ifru.ifru_hwaddr.sa_family = ARPHRD_ETHER;
1360                         }
1361 #endif
1362                         rt_memcpy(addr->sa_data, netdev->hwaddr, netdev->hwaddr_len);
1363                         return 0;
1364                     }
1365                 }
1366                 return -1;
1367             }
1368 
1369         case SIOCGIFMTU:
1370             if (!strcmp(ifr->ifr_ifrn.ifrn_name, sock->netdev->name))
1371             {
1372                 ifr->ifr_ifru.ifru_mtu = sock->netdev->mtu;
1373                 return 0;
1374             }
1375             else
1376             {
1377                 if (cur_netdev_list == RT_NULL)
1378                 {
1379                     LOG_E("ifconfig: network interface device list error.\n");
1380                     return -1;
1381                 }
1382 
1383                 for (node = &(cur_netdev_list->list); node; node = rt_slist_next(node))
1384                 {
1385                     netdev = rt_list_entry(node, struct netdev, list);
1386                     if (!strcmp(ifr->ifr_ifrn.ifrn_name, netdev->name))
1387                     {
1388                         ifr->ifr_ifru.ifru_mtu = netdev->mtu;
1389                         return 0;
1390                     }
1391                 }
1392                 return -1;
1393             }
1394         case SIOCGIFFLAGS:
1395             if (!strcmp(ifr->ifr_ifrn.ifrn_name, sock->netdev->name))
1396             {
1397                 uint16_t flags_tmp = 0;
1398                 if (sock->netdev->flags & NETDEV_FLAG_UP)
1399                     flags_tmp = flags_tmp | IFF_UP;
1400                 if (!(sock->netdev->flags & NETDEV_FLAG_ETHARP))
1401                     flags_tmp = flags_tmp | IFF_NOARP;
1402                 flags_tmp = flags_tmp | IFF_RUNNING;
1403                 ifr->ifr_ifru.ifru_flags = flags_tmp;
1404                 return 0;
1405             }
1406             else
1407             {
1408                 if (cur_netdev_list == RT_NULL)
1409                 {
1410                     LOG_E("ifconfig: network interface device list error.\n");
1411                     return -1;
1412                 }
1413 
1414                 for (node = &(cur_netdev_list->list); node; node = rt_slist_next(node))
1415                 {
1416                     netdev = rt_list_entry(node, struct netdev, list);
1417                     if (!strcmp(ifr->ifr_ifrn.ifrn_name, netdev->name))
1418                     {
1419                         uint16_t flags_tmp = 0;
1420                         if (netdev->flags & NETDEV_FLAG_UP)
1421                             flags_tmp = flags_tmp | IFF_UP;
1422                         if (!(netdev->flags & NETDEV_FLAG_ETHARP))
1423                             flags_tmp = flags_tmp | IFF_NOARP;
1424                         ifr->ifr_ifru.ifru_flags = flags_tmp;
1425                         return 0;
1426                     }
1427                 }
1428                 return -1;
1429             }
1430 
1431 
1432         case SIOCSIFFLAGS:
1433             for (node = &(cur_netdev_list->list); node; node = rt_slist_next(node))
1434             {
1435                 netdev = rt_list_entry(node, struct netdev, list);
1436                 if (!strcmp(ifr->ifr_ifrn.ifrn_name, netdev->name))
1437                 {
1438                     if ((ifr->ifr_ifru.ifru_flags & IFF_UP) == 0)
1439                     {
1440                         netdev_set_down(netdev);
1441                     }
1442                     else
1443                     {
1444                         netdev_set_up(netdev);
1445                     }
1446                     return 0;
1447                 }
1448             }
1449             return -1;
1450 
1451         case SIOCGIFCONF:
1452         {
1453             struct ifconf *ifconf_tmp;
1454             ifconf_tmp = (struct ifconf *)arg;
1455             int count_size = 0;
1456 
1457             for (node = &(cur_netdev_list->list); node; node = rt_slist_next(node))
1458             {
1459                 struct sal_ifreq sal_ifreq_temp;
1460                 count_size++;
1461                 netdev = rt_list_entry(node, struct netdev, list);
1462                 rt_strcpy(sal_ifreq_temp.ifr_ifrn.ifrn_name, netdev->name);
1463                 rt_memcpy(ifconf_tmp->ifc_ifcu.ifcu_buf, &sal_ifreq_temp, sizeof(struct sal_ifreq));
1464                 ifconf_tmp->ifc_ifcu.ifcu_buf += sizeof(struct sal_ifreq);
1465             }
1466             ifconf_tmp->ifc_len = sizeof(struct sal_ifreq) * count_size;
1467             ifconf_tmp->ifc_ifcu.ifcu_buf =  ifconf_tmp->ifc_ifcu.ifcu_buf - sizeof(struct sal_ifreq) * count_size;
1468             return 0;
1469         }
1470         case SIOCGIFINDEX:
1471         {
1472             netdev = netdev_get_by_name(ifr->ifr_ifrn.ifrn_name);
1473             if (netdev)
1474             {
1475                 ifr->ifr_ifru.ifru_ivalue = netdev->ifindex;
1476                 return 0;
1477             }
1478             return -ENODEV;
1479         }
1480         default:
1481             break;
1482         }
1483     }
1484 
1485     /* check the network interface socket opreation */
1486     SAL_NETDEV_SOCKETOPS_VALID(sock->netdev, pf, ioctlsocket);
1487 
1488     return pf->skt_ops->ioctlsocket((int)(size_t)sock->user_data, cmd, arg);
1489 }
1490 
1491 #ifdef SAL_USING_POSIX
sal_poll(struct dfs_file * file,struct rt_pollreq * req)1492 int sal_poll(struct dfs_file *file, struct rt_pollreq *req)
1493 {
1494     struct sal_socket *sock;
1495     struct sal_proto_family *pf;
1496     int socket = (int)(size_t)file->vnode->data;
1497 
1498     /* get the socket object by socket descriptor */
1499     SAL_SOCKET_OBJ_GET(sock, socket);
1500 
1501     /* check the network interface is up status  */
1502     SAL_NETDEV_IS_UP(sock->netdev);
1503     /* check the network interface socket opreation */
1504     SAL_NETDEV_SOCKETOPS_VALID(sock->netdev, pf, poll);
1505 
1506     return pf->skt_ops->poll(file, req);
1507 }
1508 #endif
1509 
sal_gethostbyname(const char * name)1510 struct hostent *sal_gethostbyname(const char *name)
1511 {
1512     struct netdev *netdev = netdev_default;
1513     struct sal_proto_family *pf;
1514 
1515     if (SAL_NETDEV_NETDBOPS_VALID(netdev, pf, gethostbyname))
1516     {
1517         return pf->netdb_ops->gethostbyname(name);
1518     }
1519     else
1520     {
1521         /* get the first network interface device with up status */
1522         netdev = netdev_get_first_by_flags(NETDEV_FLAG_UP);
1523         if (SAL_NETDEV_NETDBOPS_VALID(netdev, pf, gethostbyname))
1524         {
1525             return pf->netdb_ops->gethostbyname(name);
1526         }
1527     }
1528 
1529     return RT_NULL;
1530 }
1531 
sal_gethostbyname_r(const char * name,struct hostent * ret,char * buf,size_t buflen,struct hostent ** result,int * h_errnop)1532 int sal_gethostbyname_r(const char *name, struct hostent *ret, char *buf,
1533                         size_t buflen, struct hostent **result, int *h_errnop)
1534 {
1535     struct netdev *netdev = netdev_default;
1536     struct sal_proto_family *pf;
1537 
1538     if (SAL_NETDEV_NETDBOPS_VALID(netdev, pf, gethostbyname_r))
1539     {
1540         return pf->netdb_ops->gethostbyname_r(name, ret, buf, buflen, result, h_errnop);
1541     }
1542     else
1543     {
1544         /* get the first network interface device with up status */
1545         netdev = netdev_get_first_by_flags(NETDEV_FLAG_UP);
1546         if (SAL_NETDEV_NETDBOPS_VALID(netdev, pf, gethostbyname_r))
1547         {
1548             return pf->netdb_ops->gethostbyname_r(name, ret, buf, buflen, result, h_errnop);
1549         }
1550     }
1551 
1552     return -1;
1553 }
1554 
sal_getaddrinfo(const char * nodename,const char * servname,const struct addrinfo * hints,struct addrinfo ** res)1555 int sal_getaddrinfo(const char *nodename,
1556                     const char *servname,
1557                     const struct addrinfo *hints,
1558                     struct addrinfo **res)
1559 {
1560     struct netdev *netdev = netdev_default;
1561     struct sal_proto_family *pf;
1562     int     ret = 0;
1563     rt_uint32_t i = 0;
1564 
1565     if (SAL_NETDEV_NETDBOPS_VALID(netdev, pf, getaddrinfo))
1566     {
1567         ret = pf->netdb_ops->getaddrinfo(nodename, servname, hints, res);
1568     }
1569     else
1570     {
1571         /* get the first network interface device with up status */
1572         netdev = netdev_get_first_by_flags(NETDEV_FLAG_UP);
1573         if (SAL_NETDEV_NETDBOPS_VALID(netdev, pf, getaddrinfo))
1574         {
1575             ret = pf->netdb_ops->getaddrinfo(nodename, servname, hints, res);
1576         }
1577         else
1578         {
1579             ret = -1;
1580         }
1581     }
1582 
1583     if(ret == RT_EOK)
1584     {
1585         /*record the netdev and res*/
1586         for(i = 0; i < SAL_SOCKETS_NUM; i++)
1587         {
1588             if(sal_dev_res_tbl[i].res == RT_NULL)
1589             {
1590                 sal_dev_res_tbl[i].res = *res;
1591                 sal_dev_res_tbl[i].netdev = netdev;
1592                 break;
1593             }
1594         }
1595 
1596         RT_ASSERT((i < SAL_SOCKETS_NUM));
1597 
1598     }
1599 
1600     return ret;
1601 }
1602 
sal_freeaddrinfo(struct addrinfo * ai)1603 void sal_freeaddrinfo(struct addrinfo *ai)
1604 {
1605     struct netdev *netdev = RT_NULL;
1606     struct sal_proto_family *pf = RT_NULL;
1607     rt_uint32_t  i = 0;
1608 
1609     /*when use the multi netdev, it must free the ai use the getaddrinfo netdev */
1610     for(i = 0; i < SAL_SOCKETS_NUM; i++)
1611     {
1612         if(sal_dev_res_tbl[i].res == ai)
1613         {
1614             netdev = sal_dev_res_tbl[i].netdev;
1615             sal_dev_res_tbl[i].res = RT_NULL;
1616             sal_dev_res_tbl[i].netdev = RT_NULL;
1617             break;
1618         }
1619     }
1620     RT_ASSERT((i < SAL_SOCKETS_NUM));
1621 
1622     if (SAL_NETDBOPS_VALID(netdev, pf, freeaddrinfo))
1623     {
1624         pf->netdb_ops->freeaddrinfo(ai);
1625     }
1626 }
1627