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