1 /*
2 * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved.
3 * Copyright (c) 2020-2022 Huawei Device Co., Ltd. All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without modification,
6 * are permitted provided that the following conditions are met:
7 *
8 * 1. Redistributions of source code must retain the above copyright notice, this list of
9 * conditions and the following disclaimer.
10 *
11 * 2. Redistributions in binary form must reproduce the above copyright notice, this list
12 * of conditions and the following disclaimer in the documentation and/or other materials
13 * provided with the distribution.
14 *
15 * 3. Neither the name of the copyright holder nor the names of its contributors may be used
16 * to endorse or promote products derived from this software without specific prior written
17 * permission.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
20 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
21 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
22 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
23 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
24 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
25 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
26 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
27 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
28 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
29 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30 */
31
32 #include <lwip/sockets.h>
33 #include <lwip/priv/tcpip_priv.h>
34 #include <lwip/fixme.h>
35
36 #if LWIP_ENABLE_NET_CAPABILITY
37 #include "capability_type.h"
38 #include "capability_api.h"
39 #define BIND_SERVICE_CAP_MIN_PORT 1024
40 #endif
41
42 #define IOCTL_CMD_CASE_HANDLER() \
43 { \
44 err_t err; \
45 struct lwip_ioctl_apimsg msg; \
46 msg.sock = sock; \
47 msg.cmd = cmd; \
48 msg.argp = argp; \
49 \
50 err = tcpip_api_call(lwip_do_ioctl_impl, &msg.call); \
51 if (err != ENOSYS) { \
52 sock_set_errno(sock, err); \
53 done_socket(sock); \
54 return -(err != ERR_OK); \
55 } \
56 }
57
58 struct lwip_ioctl_apimsg {
59 struct tcpip_api_call_data call;
60 struct lwip_sock *sock;
61 long cmd;
62 void *argp;
63 };
64
65 static err_t lwip_do_ioctl_impl(struct tcpip_api_call_data *call);
66
67 static void poll_check_waiters(int s, int check_waiters);
68
69 static int lwip_socket_wrap(int domain, int type, int protocol);
lwip_socket(int domain,int type,int protocol)70 int lwip_socket(int domain, int type, int protocol)
71 {
72 return lwip_socket_wrap(domain, type, protocol);
73 }
74
75 static int lwip_setsockopt_wrap(int s, int level, int optname, const void *optval, socklen_t optlen);
lwip_setsockopt(int s,int level,int optname,const void * optval,socklen_t optlen)76 int lwip_setsockopt(int s, int level, int optname, const void *optval, socklen_t optlen)
77 {
78 return lwip_setsockopt_wrap(s, level, optname, optval, optlen);
79 }
80
81 static int lwip_bind_wrap(int s, const struct sockaddr *name, socklen_t namelen);
lwip_bind(int s,const struct sockaddr * name,socklen_t namelen)82 int lwip_bind(int s, const struct sockaddr *name, socklen_t namelen)
83 {
84 return lwip_bind_wrap(s, name, namelen);
85 }
86
87 static ssize_t lwip_sendto_wrap(int s, const void *dataptr, size_t size, int flags,
88 const struct sockaddr *to, socklen_t tolen);
lwip_sendto(int s,const void * dataptr,size_t size,int flags,const struct sockaddr * to,socklen_t tolen)89 ssize_t lwip_sendto(int s, const void *dataptr, size_t size, int flags, const struct sockaddr *to, socklen_t tolen)
90 {
91 return lwip_sendto_wrap(s, dataptr, size, flags, to, tolen);
92 }
93
94 #ifdef lwip_socket
95 #undef lwip_socket
96 #endif
97 #define lwip_socket static lwip_socket2
98 static int lwip_socket2(int domain, int type, int protocol);
99
100 #ifdef lwip_setsockopt
101 #undef lwip_setsockopt
102 #endif
103 #define lwip_setsockopt static lwip_setsockopt2
104 static int lwip_setsockopt2(int s, int level, int optname, const void *optval, socklen_t optlen);
105
106 #ifdef lwip_bind
107 #undef lwip_bind
108 #endif
109 #define lwip_bind static lwip_bind2
110 static int lwip_bind2(int s, const struct sockaddr *name, socklen_t namelen);
111
112 #ifdef lwip_sendto
113 #undef lwip_sendto
114 #endif
115 #define lwip_sendto lwip_sendto2
116 ssize_t lwip_sendto2(int s, const void *dataptr, size_t size, int flags, const struct sockaddr *to, socklen_t tolen);
117
118 #include "../api/sockets.c"
119
120 #undef lwip_socket
121 #undef lwip_setsockopt
122 #undef lwip_bind
123 #undef lwip_sendto
124
lwip_socket_wrap(int domain,int type,int protocol)125 static int lwip_socket_wrap(int domain, int type, int protocol)
126 {
127 if (domain != AF_INET && domain != AF_INET6) {
128 set_errno(EAFNOSUPPORT);
129 return -1;
130 }
131 #if LWIP_ENABLE_NET_CAPABILITY
132 if (type == SOCK_RAW && !IsCapPermit(CAP_NET_RAW)) {
133 set_errno(EPERM);
134 return -1;
135 }
136 #endif
137 return lwip_socket2(domain, type, protocol);
138 }
139
lwip_setsockopt_wrap(int s,int level,int optname,const void * optval,socklen_t optlen)140 static int lwip_setsockopt_wrap(int s, int level, int optname, const void *optval, socklen_t optlen)
141 {
142 #if LWIP_ENABLE_NET_CAPABILITY
143 if (level == SOL_SOCKET) {
144 switch (optname) {
145 #if LWIP_ENABLE_CAP_NET_BROADCAST
146 case SO_BROADCAST:
147 if (!IsCapPermit(CAP_NET_BROADCAST)) {
148 set_errno(EPERM);
149 return -1;
150 }
151 break;
152 #endif
153 case SO_DEBUG:
154 case SO_MARK:
155 case SO_PRIORITY:
156 case SO_RCVBUFFORCE:
157 case SO_SNDBUFFORCE:
158 if (!IsCapPermit(CAP_NET_ADMIN)) {
159 set_errno(EPERM);
160 return -1;
161 }
162 break;
163 default:
164 break;
165 }
166 }
167 #endif
168 return lwip_setsockopt2(s, level, optname, optval, optlen);
169 }
170
171 #if LWIP_ENABLE_NET_CAPABILITY && LWIP_ENABLE_CAP_NET_BROADCAST
ip_addr_isbroadcast_bysock(const ip_addr_t * ipaddr,int s)172 static int ip_addr_isbroadcast_bysock(const ip_addr_t *ipaddr, int s)
173 {
174 struct sockaddr sa;
175 socklen_t salen = sizeof(sa);
176
177 if (ipaddr == NULL) {
178 return 0;
179 }
180
181 if (lwip_getsockname(s, &sa, &salen) == -1) {
182 return 0;
183 }
184
185 ip_addr_t addr;
186 u16_t port;
187
188 SOCKADDR_TO_IPADDR_PORT(&sa, &addr, port);
189
190 struct netif *netif = NULL;
191 NETIF_FOREACH(netif) {
192 if (ip_addr_cmp(&netif->ip_addr, &addr)) {
193 return ip_addr_isbroadcast(ipaddr, netif);
194 }
195 for (int i = 0; i < LWIP_IPV6_NUM_ADDRESSES; i++) {
196 if (ip_addr_cmp(&netif->ip6_addr[i], &addr)) {
197 return ip_addr_isbroadcast(ipaddr, netif);
198 }
199 }
200 }
201
202 return 0;
203 }
204 #endif
205
lwip_bind_wrap(int s,const struct sockaddr * name,socklen_t namelen)206 static int lwip_bind_wrap(int s, const struct sockaddr *name, socklen_t namelen)
207 {
208 #if LWIP_ENABLE_NET_CAPABILITY
209 if ((name->sa_family == AF_INET && namelen >= sizeof(struct sockaddr_in)) ||
210 (name->sa_family == AF_INET6 && namelen >= sizeof(struct sockaddr_in6))) {
211 ip_addr_t ipaddr;
212 u16_t port;
213
214 SOCKADDR_TO_IPADDR_PORT(name, &ipaddr, port);
215
216 if (port != 0 && port < BIND_SERVICE_CAP_MIN_PORT) {
217 LWIP_ERROR("permission deny: NET_BIND_SERVICE\n", IsCapPermit(CAP_NET_BIND_SERVICE),
218 set_errno(EPERM); return -1);
219 }
220 #if LWIP_ENABLE_CAP_NET_BROADCAST
221 if (ip_addr_ismulticast(&ipaddr) || ip_addr_isbroadcast_bysock(&ipaddr, s)) {
222 LWIP_ERROR("permission deny: NET_BROADCAST\n", IsCapPermit(CAP_NET_BROADCAST),
223 set_errno(EPERM); return -1);
224 }
225 #endif
226 }
227 #endif
228
229 return lwip_bind2(s, name, namelen);
230 }
231
lwip_sendto_wrap(int s,const void * dataptr,size_t size,int flags,const struct sockaddr * to,socklen_t tolen)232 static ssize_t lwip_sendto_wrap(int s, const void *dataptr, size_t size, int flags,
233 const struct sockaddr *to, socklen_t tolen)
234 {
235 #if LWIP_ENABLE_NET_CAPABILITY
236 if (to &&
237 ((to->sa_family == AF_INET && tolen >= sizeof(struct sockaddr_in)) ||
238 (to->sa_family == AF_INET6 && tolen >= sizeof(struct sockaddr_in6)))) {
239 ip_addr_t ipaddr;
240 u16_t port;
241
242 SOCKADDR_TO_IPADDR_PORT(to, &ipaddr, port);
243 #if LWIP_ENABLE_CAP_NET_BROADCAST
244 if (ip_addr_ismulticast(&ipaddr) || ip_addr_isbroadcast_bysock(&ipaddr, s)) {
245 LWIP_ERROR("permission deny: NET_BROADCAST\n", IsCapPermit(CAP_NET_BROADCAST),
246 set_errno(EPERM); return -1);
247 }
248 #endif
249 }
250 #endif
251
252 return lwip_sendto2(s, dataptr, size, flags, to, tolen);
253 }
254
255 #if LWIP_SOCKET_SELECT || LWIP_SOCKET_POLL
256
257 struct file;
258 extern void poll_wait(struct file *filp, wait_queue_head_t *wait_address, poll_table *p);
259 extern void __wake_up_interruptible_poll(wait_queue_head_t *wait, pollevent_t key);
260
poll_check_waiters(int s,int check_waiters)261 static void poll_check_waiters(int s, int check_waiters)
262 {
263 unsigned long int_save, wq_empty;
264 pollevent_t mask = 0;
265 struct lwip_sock *sock;
266 SYS_ARCH_DECL_PROTECT(lev);
267
268 if (!check_waiters) {
269 return;
270 }
271
272 sock = get_socket(s);
273 if (!sock) {
274 return;
275 }
276
277 SYS_ARCH_PROTECT(lev);
278
279 mask |= (sock->rcvevent > 0) ? (POLLIN | POLLPRI | POLLRDNORM | POLLRDBAND) : 0;
280 mask |= (sock->sendevent != 0) ? (POLLOUT | POLLWRNORM | POLLWRBAND) : 0;
281 mask |= (sock->errevent != 0) ? (POLLERR) : 0;
282
283 SYS_ARCH_UNPROTECT(lev);
284
285 spin_lock_irqsave(&sock->wq.lock, int_save);
286 wq_empty = LOS_ListEmpty(&(sock->wq.poll_queue));
287 spin_unlock_irqrestore(&sock->wq.lock, int_save);
288
289 if (mask && !wq_empty) {
290 __wake_up_interruptible_poll(&sock->wq, mask);
291 }
292
293 done_socket(sock);
294 }
295
socks_poll(int s,poll_table * wait)296 int socks_poll(int s, poll_table *wait)
297 {
298 int ret;
299 pollevent_t mask = 0;
300 struct lwip_sock *sock;
301 SYS_ARCH_DECL_PROTECT(lev);
302
303 LWIP_ERROR("sock_poll: invalid poll_table", (wait != NULL), return -EINVAL;);
304
305 sock = get_socket(s);
306 if (!sock) {
307 LWIP_DEBUGF(SOCKETS_DEBUG, ("sock_poll: Invalid socket"));
308 set_errno(EBADF);
309 return -EBADF; /* compatible with file poll */
310 }
311
312 SYS_ARCH_PROTECT(lev);
313
314 mask |= (sock->rcvevent > 0 || sock->lastdata.pbuf) ? (POLLIN | POLLPRI | POLLRDNORM | POLLRDBAND) : 0;
315 mask |= (sock->sendevent != 0) ? (POLLOUT | POLLWRNORM | POLLWRBAND) : 0;
316 mask |= (sock->errevent != 0) ? (POLLERR) : 0;
317
318 SYS_ARCH_UNPROTECT(lev);
319
320 ret = wait->key & mask;
321 if (!ret) {
322 poll_wait(NULL, &sock->wq, wait);
323 }
324
325 done_socket(sock);
326 return ret;
327 }
328
329 #endif /* LWIP_SOCKET_SELECT || LWIP_SOCKET_POLL */
330
331 #if !LWIP_COMPAT_SOCKETS
332
333 #define API_ALIAS(old, new) \
334 extern __typeof(old) new __attribute__((__weak__, __alias__(#old)))
335
336 API_ALIAS(lwip_ioctl, ioctlsocket);
337
338 #endif /* !LWIP_COMPAT_SOCKETS */
339
340 #if LWIP_ENABLE_LOS_SHELL_CMD
341 /* get numbers of unused sockets */
get_unused_socket_num(void)342 int get_unused_socket_num(void)
343 {
344 int unused = 0;
345 SYS_ARCH_DECL_PROTECT(lev);
346
347 SYS_ARCH_PROTECT(lev);
348
349 for (int i = 0; i < NUM_SOCKETS; i++) {
350 if (sockets[i].conn == NULL) {
351 #if LWIP_NETCONN_FULLDUPLEX
352 if (sockets[i].fd_used) {
353 continue;
354 }
355 #endif
356 unused++;
357 }
358 }
359
360 SYS_ARCH_UNPROTECT(lev);
361
362 return unused;
363 }
364 #endif
365
366 /**
367 * socket ioctl
368 */
369
370 // Options for lwip ioctl
371 #define LWIP_IOCTL_ROUTE 1
372 #define LWIP_IOCTL_IF 1
373 #define LWIP_NETIF_ETHTOOL 0
374 #define LWIP_IOCTL_IPV6DPCTD 0
375 #undef LWIP_IPV6_DUP_DETECT_ATTEMPTS
376 #define LWIP_IPV6_DUP_DETECT_ATTEMPTS 0
377
378 #ifndef SIOCSIPV6DAD
379 #define SIOCSIPV6DAD _IOW('z', 0, unsigned long) /* set DAD enable/disable on netif */
380 #endif
381
382 #ifndef SIOCGIPV6DAD
383 #define SIOCGIPV6DAD _IOR('z', 1, unsigned long) /* get DAD status on netif */
384 #endif
385
386 #ifndef SIOCSIPV6DPCTD
387 #define SIOCSIPV6DPCTD _IOW('z', 2, unsigned long)
388 #endif
389
390 #ifndef SIOCGIPV6DPCTD
391 #define SIOCGIPV6DPCTD _IOR('z', 3, unsigned long)
392 #endif
393
394 #ifndef SIOCETHTOOL
395 #define SIOCETHTOOL 0x8946
396 #endif
397
398 #if LWIP_NETIF_PROMISC
399 #define NETIF_FLAG_PROMISC 0x80U
400 #endif /* LWIP_NETIF_PROMISC */
401
402
403 #if LWIP_IOCTL_ROUTE
404
405 #include <net/route.h>
406
407 #ifdef LOSCFG_NET_CONTAINER
lwip_ioctl_internal_SIOCADDRT(struct rtentry * rmten,struct net_group * group)408 static u8_t lwip_ioctl_internal_SIOCADDRT(struct rtentry *rmten, struct net_group *group)
409 #else
410 static u8_t lwip_ioctl_internal_SIOCADDRT(struct rtentry *rmten)
411 #endif
412 {
413 struct netif *netif = NULL;
414 ip_addr_t rtgw_addr;
415 u16_t rtgw_port;
416
417 #if LWIP_ENABLE_NET_CAPABILITY
418 if (!IsCapPermit(CAP_NET_ADMIN)) {
419 return EPERM;
420 }
421 #endif
422
423 SOCKADDR_TO_IPADDR_PORT(&rmten->rt_gateway, &rtgw_addr, rtgw_port);
424
425 if (!IP_IS_V4_VAL(rtgw_addr)) {
426 return EINVAL;
427 }
428
429 /* check if multicast/0/loopback */
430 if (ip_addr_ismulticast(&rtgw_addr) || ip_addr_isany(&rtgw_addr) ||
431 ip_addr_isloopback(&rtgw_addr)) {
432 return EINVAL;
433 }
434
435 /* check if reachable */
436 #ifdef LOSCFG_NET_CONTAINER
437 for (netif = group->netif_list; netif != NULL; netif = netif->next) {
438 #else
439 for (netif = netif_list; netif != NULL; netif = netif->next) {
440 #endif
441 if (ip_addr_netcmp(&rtgw_addr, &netif->ip_addr, ip_2_ip4(&netif->netmask))) {
442 break;
443 }
444 }
445
446 if (netif == NULL) {
447 return EHOSTUNREACH;
448 }
449
450 /* check if broadcast */
451 if (ip_addr_isbroadcast(&rtgw_addr, netif) != 0) {
452 return EINVAL;
453 }
454
455 /* Check flags */
456 if ((rmten->rt_flags & RTF_GATEWAY) == 0) {
457 return EINVAL;
458 }
459
460 /* Add validation */
461 #ifdef LOSCFG_NET_CONTAINER
462 if ((group->netif_default != NULL) && (group->netif_default != netif)) {
463 ip_addr_set_zero(&group->netif_default->gw);
464 (void)netif_set_default(netif, group);
465 #else
466 if ((netif_default != NULL) && (netif_default != netif)) {
467 ip_addr_set_zero(&netif_default->gw);
468 (void)netif_set_default(netif);
469 #endif
470 }
471 netif_set_gw(netif, ip_2_ip4(&rtgw_addr));
472
473 return 0;
474 }
475
476 #endif
477
478 #if LWIP_IOCTL_IF
479 #ifdef LOSCFG_NET_CONTAINER
480 static u8_t lwip_ioctl_internal_SIOCGIFCONF(struct ifreq *ifr, struct net_group *group)
481 #else
482 static u8_t lwip_ioctl_internal_SIOCGIFCONF(struct ifreq *ifr)
483 #endif
484 {
485 struct ifconf *ifc = NULL;
486 struct netif *netif = NULL;
487 struct ifreq ifreq;
488 struct sockaddr_in *sock_in = NULL;
489 int pos;
490 int len;
491 int ret;
492
493 /* Format the caller's buffer. */
494 ifc = (struct ifconf *)ifr;
495 len = ifc->ifc_len;
496
497 /* Loop over the interfaces, and write an info block for each. */
498 pos = 0;
499 #ifdef LOSCFG_NET_CONTAINER
500 for (netif = group->netif_list; netif != NULL; netif = netif->next) {
501 #else
502 for (netif = netif_list; netif != NULL; netif = netif->next) {
503 #endif
504 if (ifc->ifc_buf == NULL) {
505 pos = (pos + (int)sizeof(struct ifreq));
506 continue;
507 }
508
509 if (len < (int)sizeof(ifreq)) {
510 break;
511 }
512 (void)memset_s(&ifreq, sizeof(struct ifreq), 0, sizeof(struct ifreq));
513 if (netif->link_layer_type == LOOPBACK_IF) {
514 ret = snprintf_s(ifreq.ifr_name, IFNAMSIZ, (IFNAMSIZ - 1), "%.2s", netif->name);
515 if ((ret <= 0) || (ret >= IFNAMSIZ)) {
516 LWIP_DEBUGF(NETIF_DEBUG, ("lwip_ioctl: snprintf_s ifr_name failed."));
517 return ENOBUFS;
518 }
519 } else {
520 ret = snprintf_s(ifreq.ifr_name, IFNAMSIZ, (IFNAMSIZ - 1), "%s", netif_get_name(netif));
521 if ((ret <= 0) || (ret >= IFNAMSIZ)) {
522 LWIP_DEBUGF(NETIF_DEBUG, ("lwip_ioctl: snprintf_s ifr_name failed."));
523 return ENOBUFS;
524 }
525 }
526
527 sock_in = (struct sockaddr_in *)&ifreq.ifr_addr;
528 sock_in->sin_family = AF_INET;
529 sock_in->sin_addr.s_addr = ip_2_ip4(&netif->ip_addr)->addr;
530 if (memcpy_s(ifc->ifc_buf + pos, sizeof(struct ifreq), &ifreq, sizeof(struct ifreq)) != EOK) {
531 return ENOBUFS;
532 }
533 pos = pos + (int)sizeof(struct ifreq);
534 len = len - (int)sizeof(struct ifreq);
535 }
536
537 ifc->ifc_len = pos;
538
539 return 0;
540 }
541
542 static u8_t lwip_ioctl_internal_SIOCGIFADDR(struct ifreq *ifr)
543 {
544 struct netif *netif = NULL;
545 struct sockaddr_in *sock_in = NULL;
546
547 /* get netif ipaddr */
548 netif = netif_find(ifr->ifr_name);
549 if (netif == NULL) {
550 return ENODEV;
551 } else {
552 sock_in = (struct sockaddr_in *)&ifr->ifr_addr;
553 sock_in->sin_family = AF_INET;
554 sock_in->sin_addr.s_addr = ip_2_ip4(&netif->ip_addr)->addr;
555 return 0;
556 }
557 }
558
559 #ifndef LWIP_IPV6_PREFIX_LEN
560 #define LWIP_IPV6_PREFIX_LEN 64
561 #endif
562
563 #ifndef LWIP_NETIF_IFINDEX_MAX_EX
564 #define LWIP_NETIF_IFINDEX_MAX_EX 255
565 #endif
566
567 #include "lwip/dhcp.h"
568 #include "lwip/dhcp6.h"
569 #include "lwip/prot/dhcp.h"
570 #include "lwip/prot/dhcp6.h"
571
572 static u8_t lwip_ioctl_internal_SIOCSIFADDR_6(struct ifreq *ifr)
573 {
574 (void)ifr;
575 return ENOSYS;
576 }
577
578 #ifdef LOSCFG_NET_CONTAINER
579 static u8_t lwip_ioctl_internal_SIOCSIFADDR(struct ifreq *ifr, struct net_group *group)
580 #else
581 static u8_t lwip_ioctl_internal_SIOCSIFADDR(struct ifreq *ifr)
582 #endif
583 {
584 struct netif *netif = NULL;
585
586 struct netif *loc_netif = NULL;
587 ip_addr_t taget_addr;
588 u16_t taget_port;
589 SOCKADDR_TO_IPADDR_PORT(&ifr->ifr_addr, &taget_addr, taget_port);
590
591 #if LWIP_ENABLE_NET_CAPABILITY
592 if (!IsCapPermit(CAP_NET_ADMIN)) {
593 return EPERM;
594 }
595 #endif
596
597 /* set netif ipaddr */
598 netif = netif_find(ifr->ifr_name);
599 if (netif == NULL) {
600 return ENODEV;
601 }
602 #if LWIP_HAVE_LOOPIF
603 else if (netif->link_layer_type == LOOPBACK_IF) {
604 return EPERM;
605 }
606 #endif
607 else {
608 /* check the address is not multicast/broadcast/0/loopback */
609 if (!IP_IS_V4(&taget_addr) || ip_addr_ismulticast(&taget_addr) ||
610 ip_addr_isbroadcast(&taget_addr, netif) ||
611 ip_addr_isany(&taget_addr) ||
612 ip_addr_isloopback(&taget_addr)) {
613 return EINVAL;
614 }
615
616 /* reset gateway if new and previous ipaddr not in same net */
617 if (ip_addr_netcmp(&taget_addr, &netif->ip_addr, ip_2_ip4(&netif->netmask)) == 0) {
618 ip_addr_set_zero(&netif->gw);
619 #ifdef LOSCFG_NET_CONTAINER
620 if (netif == group->netif_default) {
621 (void)netif_set_default(NULL, group);
622 #else
623 if (netif == netif_default) {
624 (void)netif_set_default(NULL);
625 #endif
626 }
627 }
628
629 /* lwip disallow two netif sit in same net at the same time */
630 #ifdef LOSCFG_NET_CONTAINER
631 loc_netif = group->netif_list;
632 #else
633 loc_netif = netif_list;
634 #endif
635 while (loc_netif != NULL) {
636 if (loc_netif == netif) {
637 loc_netif = loc_netif->next;
638 continue;
639 }
640 if (ip_addr_cmp(&netif->netmask, &loc_netif->netmask) &&
641 ip_addr_netcmp(&loc_netif->ip_addr, &taget_addr,
642 ip_2_ip4(&netif->netmask))) {
643 return EINVAL;
644 }
645 loc_netif = loc_netif->next;
646 }
647
648 #if LWIP_DHCP
649 if ((netif_dhcp_data(netif) != NULL) &&
650 (netif_dhcp_data(netif)->state != DHCP_STATE_OFF)) {
651 (void)netif_dhcp_off(netif);
652 }
653 #endif
654
655 #if LWIP_ARP
656 /* clear ARP cache when IP address changed */
657 if ((netif->flags & NETIF_FLAG_ETHARP) != 0) {
658 etharp_cleanup_netif(netif);
659 }
660 #endif /* LWIP_ARP */
661
662 netif_set_ipaddr(netif, ip_2_ip4(&taget_addr));
663
664 return 0;
665 }
666 }
667
668 static u8_t lwip_ioctl_internal_SIOCDIFADDR_6(struct ifreq *ifr)
669 {
670 (void)ifr;
671 return ENOSYS;
672 }
673
674 #ifdef LOSCFG_NET_CONTAINER
675 static u8_t lwip_ioctl_internal_SIOCDIFADDR(struct ifreq *ifr, struct net_group *group)
676 #else
677 static u8_t lwip_ioctl_internal_SIOCDIFADDR(struct ifreq *ifr)
678 #endif
679 {
680 struct netif *netif = NULL;
681
682 ip_addr_t target_addr;
683 u16_t target_port;
684
685 SOCKADDR_TO_IPADDR_PORT(&ifr->ifr_addr, &target_addr, target_port);
686
687 #if LWIP_ENABLE_NET_CAPABILITY
688 if (!IsCapPermit(CAP_NET_ADMIN)) {
689 return EPERM;
690 }
691 #endif
692
693 /* set netif ipaddr */
694 netif = netif_find(ifr->ifr_name);
695 if (netif == NULL) {
696 return ENODEV;
697 }
698 #if LWIP_HAVE_LOOPIF
699 else if (netif->link_layer_type == LOOPBACK_IF) {
700 return EPERM;
701 }
702 #endif
703
704 /* check the address is not loopback */
705 if (!IP_IS_V4(&target_addr) || ip_addr_isloopback(&target_addr)) {
706 return EINVAL;
707 }
708
709 #if LWIP_DHCP
710 if ((netif_dhcp_data(netif) != NULL) &&
711 (netif_dhcp_data(netif)->state != DHCP_STATE_OFF)) {
712 (void)netif_dhcp_off(netif);
713 }
714 #endif
715
716 ip_addr_set_zero(&netif->gw);
717 ip_addr_set_zero(&netif->ip_addr);
718 ip_addr_set_zero(&netif->netmask);
719 #ifdef LOSCFG_NET_CONTAINER
720 if (netif == group->netif_default) {
721 (void)netif_set_default(NULL, group);
722 #else
723 if (netif == netif_default) {
724 (void)netif_set_default(NULL);
725 #endif
726 }
727
728 #if LWIP_IPV4 && LWIP_ARP
729 if ((netif->flags & NETIF_FLAG_ETHARP) != 0) {
730 etharp_cleanup_netif(netif);
731 }
732 #endif /* LWIP_IPV4 && LWIP_ARP */
733
734 return ERR_OK;
735 }
736
737 static u8_t lwip_ioctl_internal_SIOCGIFNETMASK(struct ifreq *ifr)
738 {
739 struct netif *netif = NULL;
740 struct sockaddr_in *sock_in = NULL;
741
742 /* get netif netmask */
743 netif = netif_find(ifr->ifr_name);
744 if (netif == NULL) {
745 return ENODEV;
746 } else {
747 sock_in = (struct sockaddr_in *)&ifr->ifr_netmask;
748 sock_in->sin_family = AF_INET;
749 sock_in->sin_addr.s_addr = ip_2_ip4(&netif->netmask)->addr;
750 return 0;
751 }
752 }
753
754 #ifdef LOSCFG_NET_CONTAINER
755 static u8_t lwip_ioctl_internal_SIOCSIFNETMASK(struct ifreq *ifr, struct net_group *group)
756 #else
757 static u8_t lwip_ioctl_internal_SIOCSIFNETMASK(struct ifreq *ifr)
758 #endif
759 {
760 struct netif *netif = NULL;
761
762 struct netif *loc_netif = NULL;
763 ip_addr_t taget_addr;
764 u16_t taget_port;
765 SOCKADDR_TO_IPADDR_PORT(&ifr->ifr_addr, &taget_addr, taget_port);
766
767 #if LWIP_ENABLE_NET_CAPABILITY
768 if (!IsCapPermit(CAP_NET_ADMIN)) {
769 return EPERM;
770 }
771 #endif
772
773 if (!IP_IS_V4(&taget_addr)) {
774 return EINVAL;
775 }
776
777 /* set netif netmask */
778 netif = netif_find(ifr->ifr_name);
779 if (netif == NULL) {
780 return ENODEV;
781 }
782 #if LWIP_HAVE_LOOPIF
783 else if (netif->link_layer_type == LOOPBACK_IF) {
784 return EPERM;
785 }
786 #endif
787 else {
788 if (ip_addr_cmp(&netif->netmask, &taget_addr)) {
789 return 0;
790 }
791 /* check data valid */
792 #ifdef LOSCFG_NET_CONTAINER
793 if (ip_addr_netmask_valid(ip_2_ip4(&taget_addr)) == 0) {
794 #else
795 if (ip_addr_netmask_valid(ip_2_ip4(&taget_addr)) != 0) {
796 #endif
797 return EINVAL;
798 }
799
800 /* lwip disallow two netif sit in same net at the same time */
801 #ifdef LOSCFG_NET_CONTAINER
802 loc_netif = group->netif_list;
803 #else
804 loc_netif = netif_list;
805 #endif
806 while (loc_netif != NULL) {
807 if (loc_netif == netif) {
808 loc_netif = loc_netif->next;
809 continue;
810 }
811 if (ip_addr_cmp(&loc_netif->netmask, &taget_addr) &&
812 ip_addr_netcmp(&loc_netif->ip_addr,
813 &netif->ip_addr, ip_2_ip4(&loc_netif->netmask))) {
814 return EINVAL;
815 }
816 loc_netif = loc_netif->next;
817 }
818
819 #if LWIP_DHCP
820 if ((netif_dhcp_data(netif) != NULL) &&
821 (netif_dhcp_data(netif)->state != DHCP_STATE_OFF)) {
822 (void)netif_dhcp_off(netif);
823 }
824 #endif
825
826 netif_set_netmask(netif, ip_2_ip4(&taget_addr));
827
828 /* check if gateway still reachable */
829 if (!ip_addr_netcmp(&netif->gw, &netif->ip_addr, ip_2_ip4(&taget_addr))) {
830 ip_addr_set_zero(&(netif->gw));
831 #ifdef LOSCFG_NET_CONTAINER
832 if (netif == group->netif_default) {
833 (void)netif_set_default(NULL, group);
834 #else
835 if (netif == netif_default) {
836 (void)netif_set_default(NULL);
837 #endif
838 }
839 }
840 return 0;
841 }
842 }
843
844 static u8_t lwip_ioctl_internal_SIOCSIFHWADDR(struct ifreq *ifr)
845 {
846 struct netif *netif = NULL;
847 err_t ret;
848
849 #if LWIP_ENABLE_NET_CAPABILITY
850 if (!IsCapPermit(CAP_NET_ADMIN)) {
851 return EPERM;
852 }
853 #endif
854
855 /* set netif hw addr */
856 netif = netif_find(ifr->ifr_name);
857 if (netif == NULL) {
858 return ENODEV;
859 }
860 #if LWIP_HAVE_LOOPIF
861 else if (netif->link_layer_type == LOOPBACK_IF) {
862 return EPERM;
863 }
864 #endif
865 else {
866 /* bring netif down to clear all Neighbor Cache Entry */
867 (void)netif_set_down(netif);
868
869 ret = netif_set_hwaddr(netif, (const unsigned char *)ifr->ifr_hwaddr.sa_data, netif->hwaddr_len);
870 if (ret != ERR_OK) {
871 (void)netif_set_up(netif);
872 return err_to_errno(ret);
873 }
874
875 /*
876 * bring netif up to try to send GARP/IGMP/NA/MLD/RS. GARP and NA would
877 * make the neighboring nodes update their Neighbor Cache immediately.
878 */
879 (void)netif_set_up(netif);
880 return 0;
881 }
882 }
883
884 static u8_t lwip_ioctl_internal_SIOCGIFHWADDR(struct ifreq *ifr)
885 {
886 struct netif *netif = NULL;
887
888 /* get netif hw addr */
889 netif = netif_find(ifr->ifr_name);
890 if (netif == NULL) {
891 return ENODEV;
892 }
893 #if LWIP_HAVE_LOOPIF
894 else if (netif->link_layer_type == LOOPBACK_IF) {
895 return EPERM;
896 }
897 #endif /* LWIP_HAVE_LOOPIF */
898 else {
899 if (memcpy_s((void *)ifr->ifr_hwaddr.sa_data, sizeof(ifr->ifr_hwaddr.sa_data),
900 (void *)netif->hwaddr, netif->hwaddr_len) != EOK) {
901 return EINVAL;
902 }
903 return 0;
904 }
905 }
906
907 static u8_t lwip_ioctl_internal_SIOCSIFFLAGS(struct ifreq *ifr)
908 {
909 struct netif *netif = NULL;
910
911 #if LWIP_ENABLE_NET_CAPABILITY
912 if (!IsCapPermit(CAP_NET_ADMIN)) {
913 return EPERM;
914 }
915 #endif
916
917 /* set netif hw addr */
918 netif = netif_find(ifr->ifr_name);
919 if (netif == NULL) {
920 return ENODEV;
921 }
922 #if LWIP_HAVE_LOOPIF
923 else if (netif->link_layer_type == LOOPBACK_IF) {
924 return EPERM;
925 }
926 #endif /* LWIP_HAVE_LOOPIF */
927 else {
928 if (((unsigned short)ifr->ifr_flags & IFF_UP) && !(netif->flags & NETIF_FLAG_UP)) {
929 (void)netif_set_up(netif);
930 } else if (!((unsigned short)ifr->ifr_flags & IFF_UP) && (netif->flags & NETIF_FLAG_UP)) {
931 (void)netif_set_down(netif);
932 }
933 if (((unsigned short)ifr->ifr_flags & IFF_RUNNING) && !(netif->flags & NETIF_FLAG_LINK_UP)) {
934 (void)netif_set_link_up(netif);
935 } else if (!((unsigned short)ifr->ifr_flags & IFF_RUNNING) && (netif->flags & NETIF_FLAG_LINK_UP)) {
936 (void)netif_set_link_down(netif);
937 }
938
939 if ((unsigned short)ifr->ifr_flags & IFF_BROADCAST) {
940 netif->flags |= NETIF_FLAG_BROADCAST;
941 } else {
942 netif->flags = netif->flags & (~NETIF_FLAG_BROADCAST);
943 }
944 if ((unsigned short)ifr->ifr_flags & IFF_NOARP) {
945 netif->flags = (netif->flags & (~NETIF_FLAG_ETHARP));
946 } else {
947 netif->flags |= NETIF_FLAG_ETHARP;
948 }
949
950 if ((unsigned short)ifr->ifr_flags & IFF_MULTICAST) {
951 #if LWIP_IGMP
952 netif->flags |= NETIF_FLAG_IGMP;
953 #endif /* LWIP_IGMP */
954 #if LWIP_IPV6 && LWIP_IPV6_MLD
955 netif->flags |= NETIF_FLAG_MLD6;
956 #endif /* LWIP_IPV6_MLD */
957 } else {
958 #if LWIP_IGMP
959 netif->flags = (netif->flags & ~NETIF_FLAG_IGMP);
960 #endif /* LWIP_IGMP */
961 #if LWIP_IPV6 && LWIP_IPV6_MLD
962 netif->flags = (netif->flags & ~NETIF_FLAG_MLD6);
963 #endif /* LWIP_IPV6_MLD */
964 }
965
966 #if LWIP_DHCP
967 if ((unsigned short)ifr->ifr_flags & IFF_DYNAMIC) {
968 (void)dhcp_start(netif);
969 } else {
970 dhcp_stop(netif);
971 #if !LWIP_DHCP_SUBSTITUTE
972 dhcp_cleanup(netif);
973 #endif
974 }
975 #endif
976
977 #if LWIP_NETIF_PROMISC
978 if (((unsigned short)ifr->ifr_flags & IFF_PROMISC)) {
979 netif->flags |= NETIF_FLAG_PROMISC;
980 } else {
981 netif->flags &= ~NETIF_FLAG_PROMISC;
982 }
983 if (netif->drv_config) {
984 netif->drv_config(netif, IFF_PROMISC, !!((unsigned short)ifr->ifr_flags & IFF_PROMISC));
985 }
986 #endif /* LWIP_NETIF_PROMISC */
987 return 0;
988 }
989 }
990
991 static u8_t lwip_ioctl_internal_SIOCGIFFLAGS(struct ifreq *ifr)
992 {
993 struct netif *netif = NULL;
994
995 /* set netif hw addr */
996 netif = netif_find(ifr->ifr_name);
997 if (netif == NULL) {
998 return ENODEV;
999 } else {
1000 if (netif->flags & NETIF_FLAG_UP) {
1001 ifr->ifr_flags = ((unsigned short)(ifr->ifr_flags)) | IFF_UP;
1002 } else {
1003 ifr->ifr_flags = ((unsigned short)(ifr->ifr_flags)) & ~IFF_UP;
1004 }
1005 if (netif->flags & NETIF_FLAG_LINK_UP) {
1006 ifr->ifr_flags = ((unsigned short)(ifr->ifr_flags)) | IFF_RUNNING;
1007 } else {
1008 ifr->ifr_flags = ((unsigned short)(ifr->ifr_flags)) & ~IFF_RUNNING;
1009 }
1010 if (netif->flags & NETIF_FLAG_BROADCAST) {
1011 ifr->ifr_flags = ((unsigned short)(ifr->ifr_flags)) | IFF_BROADCAST;
1012 } else {
1013 ifr->ifr_flags = ((unsigned short)(ifr->ifr_flags)) & ~IFF_BROADCAST;
1014 }
1015 if (netif->flags & NETIF_FLAG_ETHARP) {
1016 ifr->ifr_flags = ((unsigned short)(ifr->ifr_flags)) & ~IFF_NOARP;
1017 } else {
1018 ifr->ifr_flags = ((unsigned short)(ifr->ifr_flags)) | IFF_NOARP;
1019 }
1020
1021 #if LWIP_IGMP || LWIP_IPV6_MLD
1022 if (
1023 #if LWIP_IGMP
1024 (netif->flags & NETIF_FLAG_IGMP)
1025 #endif /* LWIP_IGMP */
1026 #if LWIP_IGMP && LWIP_IPV6_MLD
1027 ||
1028 #endif /* LWIP_IGMP && LWIP_IPV6_MLD */
1029 #if LWIP_IPV6_MLD
1030 (netif->flags & NETIF_FLAG_MLD6)
1031 #endif /* LWIP_IPV6_MLD */
1032 ) {
1033 ifr->ifr_flags = (short)((unsigned short)ifr->ifr_flags | IFF_MULTICAST);
1034 } else {
1035 ifr->ifr_flags = (short)((unsigned short)ifr->ifr_flags & (~IFF_MULTICAST));
1036 }
1037 #endif /* LWIP_IGMP || LWIP_IPV6_MLD */
1038
1039 #if LWIP_DHCP
1040 if (dhcp_supplied_address(netif)) {
1041 ifr->ifr_flags = (short)((unsigned short)ifr->ifr_flags | IFF_DYNAMIC);
1042 } else {
1043 ifr->ifr_flags = (short)((unsigned short)ifr->ifr_flags & (~IFF_DYNAMIC));
1044 }
1045 #endif
1046
1047 #if LWIP_HAVE_LOOPIF
1048 if (netif->link_layer_type == LOOPBACK_IF) {
1049 ifr->ifr_flags = ((unsigned short)(ifr->ifr_flags)) | IFF_LOOPBACK;
1050 }
1051 #endif
1052
1053 #if LWIP_NETIF_PROMISC
1054 if (netif->flags & NETIF_FLAG_PROMISC) {
1055 ifr->ifr_flags = ((unsigned short)(ifr->ifr_flags)) | IFF_PROMISC;
1056 } else {
1057 ifr->ifr_flags = ((unsigned short)(ifr->ifr_flags)) & ~IFF_PROMISC;
1058 }
1059 #endif /* LWIP_NETIF_PROMISC */
1060
1061 return 0;
1062 }
1063 }
1064
1065 #ifdef LOSCFG_NET_CONTAINER
1066 static u8_t lwip_ioctl_internal_SIOCGIFNAME(struct ifreq *ifr, struct net_group *group)
1067 #else
1068 static u8_t lwip_ioctl_internal_SIOCGIFNAME(struct ifreq *ifr)
1069 #endif
1070 {
1071 struct netif *netif = NULL;
1072 int ret;
1073 #ifdef LOSCFG_NET_CONTAINER
1074 for (netif = group->netif_list; netif != NULL; netif = netif->next) {
1075 #else
1076 for (netif = netif_list; netif != NULL; netif = netif->next) {
1077 #endif
1078 if (ifr->ifr_ifindex == netif_get_index(netif)) {
1079 break;
1080 }
1081 }
1082
1083 if (netif == NULL) {
1084 return ENODEV;
1085 } else {
1086 if (netif->link_layer_type == LOOPBACK_IF) {
1087 ret = snprintf_s(ifr->ifr_name, IFNAMSIZ, (IFNAMSIZ - 1), "%.2s", netif->name);
1088 if ((ret <= 0) || (ret >= IFNAMSIZ)) {
1089 return ENOBUFS;
1090 }
1091 } else {
1092 ret = snprintf_s(ifr->ifr_name, IFNAMSIZ, (IFNAMSIZ - 1), "%s", netif_get_name(netif));
1093 if ((ret <= 0) || (ret >= IFNAMSIZ)) {
1094 return ENOBUFS;
1095 }
1096 }
1097 return 0;
1098 }
1099 }
1100
1101 static bool lwip_validate_ifname(const char *name, u8_t *let_pos)
1102 {
1103 unsigned short num_pos = 0;
1104 unsigned short letter_pos = 0;
1105 unsigned short pos = 0;
1106 bool have_num = 0;
1107
1108 /* if the first position of variable name is not letter, such as '6eth2' */
1109 if (((*name >= 'a') && (*name <= 'z')) || ((*name >= 'A') && (*name <= 'Z'))) {
1110 return 0;
1111 }
1112
1113 /* check if the position of letter is bigger than the the position of digital */
1114 while (*name != '\0') {
1115 if ((*name >= '0') && (*name <= '9')) {
1116 num_pos = pos;
1117 have_num = 1;
1118 } else if (((*name >= 'a') && (*name <= 'z')) || ((*name >= 'A') && (*name <= 'Z'))) {
1119 letter_pos = pos;
1120 if (have_num != 0) {
1121 return 0;
1122 }
1123 } else {
1124 return 0;
1125 }
1126 pos++;
1127 name++;
1128 }
1129
1130 /* for the speacil case as all position of variable name is letter, such as 'ethabc' */
1131 if (num_pos == 0) {
1132 return 0;
1133 }
1134
1135 /* cheak if the digital in the variable name is bigger than 255, such as 'eth266' */
1136 if (atoi(name - (pos - letter_pos - 1)) > 255) {
1137 return 0;
1138 }
1139
1140 *let_pos = (u8_t)letter_pos;
1141
1142 return 1;
1143 }
1144
1145 static u8_t lwip_ioctl_internal_SIOCSIFNAME(struct ifreq *ifr)
1146 {
1147 struct netif *netif = NULL;
1148 u8_t letter_pos = 0;
1149
1150 #if LWIP_ENABLE_NET_CAPABILITY
1151 if (!IsCapPermit(CAP_NET_ADMIN)) {
1152 return EPERM;
1153 }
1154 #endif
1155
1156 netif = netif_find(ifr->ifr_name);
1157 if (netif == NULL) {
1158 return ENODEV;
1159 } else if (netif->link_layer_type == LOOPBACK_IF) {
1160 return EPERM;
1161 } else if ((netif->flags & IFF_UP) != 0) {
1162 return EBUSY;
1163 } else {
1164 if (strncmp(ifr->ifr_name, ifr->ifr_newname, IFNAMSIZ) == 0) {
1165 /* not change */
1166 return 0;
1167 }
1168
1169 ifr->ifr_newname[IFNAMSIZ - 1] = '\0';
1170 if ((lwip_validate_ifname(ifr->ifr_newname, &letter_pos) == 0) || (strlen(ifr->ifr_newname) > (IFNAMSIZ - 1))) {
1171 return EINVAL;
1172 }
1173
1174 if (strncpy_s(netif->full_name, sizeof(netif->full_name), ifr->ifr_newname, strlen(ifr->ifr_newname)) != EOK) {
1175 return EINVAL;
1176 }
1177 }
1178
1179 return 0;
1180 }
1181
1182 static u8_t lwip_ioctl_internal_SIOCGIFINDEX(struct ifreq *ifr)
1183 {
1184 struct netif *netif = NULL;
1185
1186 netif = netif_find(ifr->ifr_name);
1187 if (netif == NULL) {
1188 return ENODEV;
1189 } else {
1190 ifr->ifr_ifindex = netif_get_index(netif);
1191 return 0;
1192 }
1193 }
1194
1195 static u8_t lwip_ioctl_internal_SIOCSIFMTU(struct ifreq *ifr)
1196 {
1197 struct netif *netif = NULL;
1198
1199 #if LWIP_ENABLE_NET_CAPABILITY
1200 if (!IsCapPermit(CAP_NET_ADMIN)) {
1201 return EPERM;
1202 }
1203 #endif
1204
1205 /* set netif hw addr */
1206 netif = netif_find(ifr->ifr_name);
1207 if (netif == NULL) {
1208 return ENODEV;
1209 }
1210 #if LWIP_HAVE_LOOPIF
1211 /* the mtu of loopif is not used. */
1212 else if (netif->link_layer_type == LOOPBACK_IF) {
1213 return EPERM;
1214 }
1215 #endif
1216 else {
1217 if (ERR_OK != netif_set_mtu(netif, (u16_t)ifr->ifr_mtu)) {
1218 return EINVAL;
1219 }
1220
1221 return 0;
1222 }
1223 }
1224
1225 static u8_t lwip_ioctl_internal_SIOCGIFMTU(struct ifreq *ifr)
1226 {
1227 struct netif *netif = NULL;
1228
1229 /* get netif hw addr */
1230 netif = netif_find(ifr->ifr_name);
1231 if (netif == NULL) {
1232 return ENODEV;
1233 } else {
1234 ifr->ifr_mtu = netif->mtu;
1235 return 0;
1236 }
1237 }
1238
1239 static u8_t lwip_ioctl_internal_SIOCGIFBRDADDR(struct ifreq *ifr)
1240 {
1241 struct netif *netif = NULL;
1242 struct sockaddr_in *sock_in = NULL;
1243
1244 /* get netif subnet broadcast addr */
1245 netif = netif_find(ifr->ifr_name);
1246 if (netif == NULL) {
1247 return ENODEV;
1248 }
1249 if (ip4_addr_isany_val(*(ip_2_ip4(&netif->netmask)))) {
1250 return ENXIO;
1251 }
1252 sock_in = (struct sockaddr_in *)&ifr->ifr_addr;
1253 sock_in->sin_family = AF_INET;
1254 sock_in->sin_addr.s_addr = (ip_2_ip4(&((netif)->ip_addr))->addr | ~(ip_2_ip4(&netif->netmask)->addr));
1255 return 0;
1256 }
1257
1258 #endif /* LWIP_IOCTL_IF */
1259
1260 #if LWIP_NETIF_ETHTOOL
1261
1262 static s32_t lwip_ioctl_internal_SIOCETHTOOL(struct ifreq *ifr)
1263 {
1264 struct netif *netif;
1265
1266 #if LWIP_ENABLE_NET_CAPABILITY
1267 if (!IsCapPermit(CAP_NET_ADMIN)) {
1268 return EPERM;
1269 }
1270 #endif
1271
1272 netif = netif_find(ifr->ifr_name);
1273 if (netif == NULL) {
1274 return ENODEV;
1275 } else {
1276 return dev_ethtool(netif, ifr);
1277 }
1278 }
1279
1280 #endif
1281
1282 #if LWIP_IPV6
1283 #if LWIP_IPV6_DUP_DETECT_ATTEMPTS
1284
1285 static u8_t lwip_ioctl_internal_SIOCSIPV6DAD(struct ifreq *ifr)
1286 {
1287 #if LWIP_ENABLE_NET_CAPABILITY
1288 if (!IsCapPermit(CAP_NET_ADMIN)) {
1289 return EPERM;
1290 }
1291 #endif
1292
1293 struct netif *tmpnetif = netif_find(ifr->ifr_name);
1294 if (tmpnetif == NULL) {
1295 LWIP_DEBUGF(SOCKETS_DEBUG, ("Interface not found.\n"));
1296 return ENODEV;
1297 }
1298
1299 if ((ifr->ifr_ifru.ifru_ivalue != 0) && (ifr->ifr_ifru.ifru_ivalue != 1)) {
1300 LWIP_DEBUGF(SOCKETS_DEBUG, ("Invalid ioctl argument(ifru_ivalue 0/1).\n"));
1301 return EBADRQC;
1302 }
1303
1304 if (ifr->ifr_ifru.ifru_ivalue == 1) {
1305 tmpnetif->ipv6_flags = (tmpnetif->ipv6_flags | LWIP_IPV6_ND6_FLAG_DAD);
1306
1307 LWIP_DEBUGF(SOCKETS_DEBUG, ("DAD turned on through ioctl for %s iface index %u \n",
1308 tmpnetif->name, tmpnetif->num));
1309 } else {
1310 tmpnetif->ipv6_flags = (tmpnetif->ipv6_flags & ((~LWIP_IPV6_ND6_FLAG_DAD) & 0xffU));
1311
1312 LWIP_DEBUGF(SOCKETS_DEBUG, ("DAD turned off through ioctl for %s iface index %u \n",
1313 tmpnetif->name, tmpnetif->num));
1314 }
1315 return 0;
1316 }
1317
1318 static u8_t lwip_ioctl_internal_SIOCGIPV6DAD(struct ifreq *ifr)
1319 {
1320 struct netif *tmpnetif = netif_find(ifr->ifr_name);
1321 if (tmpnetif == NULL) {
1322 LWIP_DEBUGF(SOCKETS_DEBUG, ("Interface not found.\n"));
1323 return ENODEV;
1324 }
1325 ifr->ifr_ifru.ifru_ivalue = (tmpnetif->ipv6_flags & LWIP_IPV6_ND6_FLAG_DAD) ? 1 : 0;
1326 return 0;
1327 }
1328
1329 #endif
1330
1331 #if LWIP_IOCTL_IPV6DPCTD
1332
1333 static u8_t lwip_ioctl_internal_SIOCSIPV6DPCTD(struct ifreq *ifr)
1334 {
1335 #if LWIP_ENABLE_NET_CAPABILITY
1336 if (!IsCapPermit(CAP_NET_ADMIN)) {
1337 return EPERM;
1338 }
1339 #endif
1340
1341 struct netif *tmpnetif = netif_find(ifr->ifr_name);
1342 if (tmpnetif == NULL) {
1343 LWIP_DEBUGF(SOCKETS_DEBUG, ("Interface not found.\n"));
1344 return ENODEV;
1345 }
1346 if ((ifr->ifr_ifru.ifru_ivalue != 0) && (ifr->ifr_ifru.ifru_ivalue != 1)) {
1347 LWIP_DEBUGF(SOCKETS_DEBUG, ("Invalid ioctl argument(ifru_ivalue 0/1).\n"));
1348 return EBADRQC;
1349 }
1350 if (ifr->ifr_ifru.ifru_ivalue == 1) {
1351 tmpnetif->ipv6_flags = (tmpnetif->ipv6_flags | LWIP_IPV6_ND6_FLAG_DEPRECATED);
1352 LWIP_DEBUGF(SOCKETS_DEBUG, ("Deprecation turned on through ioctl for %s iface index %u \n",
1353 tmpnetif->name, tmpnetif->num));
1354 } else {
1355 tmpnetif->ipv6_flags = (tmpnetif->ipv6_flags & ((~LWIP_IPV6_ND6_FLAG_DEPRECATED) & 0xffU));
1356 LWIP_DEBUGF(SOCKETS_DEBUG, ("Deprecation turned off through ioctl for %s iface index %u \n",
1357 tmpnetif->name, tmpnetif->num));
1358 }
1359 return 0;
1360 }
1361
1362 static u8_t lwip_ioctl_internal_SIOCGIPV6DPCTD(struct ifreq *ifr)
1363 {
1364 struct netif *tmpnetif = netif_find(ifr->ifr_name);
1365 if (tmpnetif == NULL) {
1366 LWIP_DEBUGF(SOCKETS_DEBUG, ("Interface not found.\n"));
1367 return ENODEV;
1368 }
1369
1370 ifr->ifr_ifru.ifru_ivalue = (tmpnetif->ipv6_flags & LWIP_IPV6_ND6_FLAG_DEPRECATED) ? 1 : 0;
1371 return 0;
1372 }
1373
1374 #endif /* LWIP_IOCTL_IPV6DPCTD */
1375 #endif
1376
1377 static u8_t lwip_ioctl_impl(const struct lwip_sock *sock, long cmd, void *argp)
1378 {
1379 u8_t err = 0;
1380 #if LWIP_NETIF_ETHTOOL
1381 s32_t ret;
1382 #endif
1383 #if LWIP_IPV6_DUP_DETECT_ATTEMPTS || LWIP_IOCTL_IPV6DPCTD || LWIP_IOCTL_IF || LWIP_NETIF_ETHTOOL
1384 struct ifreq *ifr = (struct ifreq *)argp;
1385 #endif
1386 #if LWIP_IOCTL_ROUTE
1387 struct rtentry *rmten = (struct rtentry *)argp;
1388 #endif
1389 #if LWIP_IPV6_DUP_DETECT_ATTEMPTS || LWIP_IOCTL_IPV6DPCTD || LWIP_IOCTL_ROUTE || LWIP_IOCTL_IF
1390 bool is_ipv6 = 0;
1391
1392 /* allow it only on IPv6 sockets... */
1393 is_ipv6 = NETCONNTYPE_ISIPV6((unsigned int)(sock->conn->type));
1394 #endif
1395 #ifdef LOSCFG_NET_CONTAINER
1396 struct net_group *group = get_net_group_from_ippcb(sock->conn->pcb.ip);
1397 #endif
1398 switch ((u32_t)cmd) {
1399 #if LWIP_IPV6
1400 #if LWIP_IPV6_DUP_DETECT_ATTEMPTS
1401 case SIOCSIPV6DAD:
1402 /* allow it only on IPv6 sockets... */
1403 if (is_ipv6 == 0) {
1404 err = EINVAL;
1405 } else {
1406 err = lwip_ioctl_internal_SIOCSIPV6DAD(ifr);
1407 }
1408 break;
1409 case SIOCGIPV6DAD:
1410 /* allow it only on IPv6 sockets... */
1411 if (is_ipv6 == 0) {
1412 err = EINVAL;
1413 } else {
1414 err = lwip_ioctl_internal_SIOCGIPV6DAD(ifr);
1415 }
1416 break;
1417 #endif /* LWIP_IPV6_DUP_DETECT_ATTEMPTS */
1418 #if LWIP_IOCTL_IPV6DPCTD
1419 case SIOCSIPV6DPCTD:
1420 /* allow it only on IPv6 sockets... */
1421 if (is_ipv6 == 0) {
1422 err = EINVAL;
1423 } else {
1424 err = lwip_ioctl_internal_SIOCSIPV6DPCTD(ifr);
1425 }
1426 break;
1427 case SIOCGIPV6DPCTD:
1428 /* allow it only on IPv6 sockets... */
1429 if (is_ipv6 == 0) {
1430 err = EINVAL;
1431 } else {
1432 err = lwip_ioctl_internal_SIOCGIPV6DPCTD(ifr);
1433 }
1434 break;
1435 #endif
1436 #endif /* LWIP_IPV6 */
1437 #if LWIP_IOCTL_ROUTE
1438 case SIOCADDRT:
1439 /* Do not allow if socket is AF_INET6 */
1440 if (is_ipv6 != 0) {
1441 err = EINVAL;
1442 } else {
1443 #ifdef LOSCFG_NET_CONTAINER
1444 err = lwip_ioctl_internal_SIOCADDRT(rmten, group);
1445 #else
1446 err = lwip_ioctl_internal_SIOCADDRT(rmten);
1447 #endif
1448 }
1449 break;
1450 #endif
1451 #if LWIP_IOCTL_IF
1452 case SIOCGIFCONF:
1453 /* Do not allow if socket is AF_INET6 */
1454 if (is_ipv6 != 0) {
1455 err = EINVAL;
1456 } else {
1457 #ifdef LOSCFG_NET_CONTAINER
1458 err = lwip_ioctl_internal_SIOCGIFCONF(ifr, group);
1459 #else
1460 err = lwip_ioctl_internal_SIOCGIFCONF(ifr);
1461 #endif
1462 }
1463 break;
1464 case SIOCGIFADDR:
1465 if (is_ipv6 != 0) {
1466 err = EINVAL;
1467 } else {
1468 err = lwip_ioctl_internal_SIOCGIFADDR(ifr);
1469 }
1470 break;
1471 case SIOCSIFADDR:
1472 if (is_ipv6 != 0) {
1473 err = lwip_ioctl_internal_SIOCSIFADDR_6(ifr);
1474 } else {
1475 #ifdef LOSCFG_NET_CONTAINER
1476 err = lwip_ioctl_internal_SIOCSIFADDR(ifr, group);
1477 #else
1478 err = lwip_ioctl_internal_SIOCSIFADDR(ifr);
1479 #endif
1480 }
1481 break;
1482 case SIOCDIFADDR:
1483 /* Delete interface address */
1484 if (is_ipv6 != 0) {
1485 err = lwip_ioctl_internal_SIOCDIFADDR_6(ifr);
1486 } else {
1487 #ifdef LOSCFG_NET_CONTAINER
1488 err = lwip_ioctl_internal_SIOCDIFADDR(ifr, group);
1489 #else
1490 err = lwip_ioctl_internal_SIOCDIFADDR(ifr);
1491 #endif
1492 }
1493 break;
1494 case SIOCGIFNETMASK:
1495 if (is_ipv6 != 0) {
1496 err = EINVAL;
1497 } else {
1498 err = lwip_ioctl_internal_SIOCGIFNETMASK(ifr);
1499 }
1500 break;
1501 case SIOCSIFNETMASK:
1502 if (is_ipv6 != 0) {
1503 err = EINVAL;
1504 } else {
1505 #ifdef LOSCFG_NET_CONTAINER
1506 err = lwip_ioctl_internal_SIOCSIFNETMASK(ifr, group);
1507 #else
1508 err = lwip_ioctl_internal_SIOCSIFNETMASK(ifr);
1509 #endif
1510 }
1511 break;
1512 case SIOCSIFHWADDR:
1513 err = lwip_ioctl_internal_SIOCSIFHWADDR(ifr);
1514 break;
1515 case SIOCGIFHWADDR:
1516 err = lwip_ioctl_internal_SIOCGIFHWADDR(ifr);
1517 break;
1518 case SIOCSIFFLAGS:
1519 err = lwip_ioctl_internal_SIOCSIFFLAGS(ifr);
1520 break;
1521 case SIOCGIFFLAGS:
1522 err = lwip_ioctl_internal_SIOCGIFFLAGS(ifr);
1523 break;
1524 case SIOCGIFNAME:
1525 #ifdef LOSCFG_NET_CONTAINER
1526 err = lwip_ioctl_internal_SIOCGIFNAME(ifr, group);
1527 #else
1528 err = lwip_ioctl_internal_SIOCGIFNAME(ifr);
1529 #endif
1530 break;
1531 case SIOCSIFNAME:
1532 err = lwip_ioctl_internal_SIOCSIFNAME(ifr);
1533 break;
1534 /* Need to support the get index through ioctl
1535 * As of now the options is restricted to PF_PACKET scenario , so removed the compiler flag Begin
1536 */
1537 case SIOCGIFINDEX:
1538 err = lwip_ioctl_internal_SIOCGIFINDEX(ifr);
1539 break;
1540 case SIOCGIFMTU:
1541 err = lwip_ioctl_internal_SIOCGIFMTU(ifr);
1542 break;
1543 case SIOCSIFMTU:
1544 err = lwip_ioctl_internal_SIOCSIFMTU(ifr);
1545 break;
1546 case SIOCGIFBRDADDR:
1547 if (is_ipv6 != 0) {
1548 err = EINVAL;
1549 } else {
1550 err = lwip_ioctl_internal_SIOCGIFBRDADDR(ifr);
1551 }
1552 break;
1553 #endif /* LWIP_IOCTL_IF */
1554 #if LWIP_NETIF_ETHTOOL
1555 case SIOCETHTOOL:
1556 ret = lwip_ioctl_internal_SIOCETHTOOL(ifr);
1557 if (ret != 0) {
1558 /* an IO error happened */
1559 err = EIO;
1560 }
1561 break;
1562 #endif
1563 /* START For cmd = -1 stack has to treat it as Invalid Input and return EINVAL */
1564 case 0xFFFFFFFF:
1565 err = EINVAL;
1566 LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_ioctl_impl(INVALID: 0x%lx)\n", cmd));
1567 break;
1568 default:
1569 err = ENOSYS;
1570 LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_ioctl(UNIMPL: 0x%lx)\n", cmd));
1571 break;
1572 }
1573
1574 return err;
1575 }
1576
1577 static err_t lwip_do_ioctl_impl(struct tcpip_api_call_data *call)
1578 {
1579 struct lwip_ioctl_apimsg *msg = (struct lwip_ioctl_apimsg *)(void *)call;
1580 return lwip_ioctl_impl(msg->sock, msg->cmd, msg->argp);
1581 }
1582
1583 #include "los_vm_map.h"
1584 #include "user_copy.h"
1585 static int do_ioctl_SIOCGIFCONF(int sockfd, long cmd, void *argp)
1586 {
1587 int nbytes;
1588 struct ifconf ifc;
1589 char *buf_bak = NULL;
1590 int ret;
1591
1592 if (LOS_ArchCopyFromUser(&ifc, argp, sizeof(struct ifconf)) != 0) {
1593 set_errno(EFAULT);
1594 return -1;
1595 }
1596 nbytes = ifc.ifc_len;
1597 if (nbytes <= 0) {
1598 set_errno(EINVAL);
1599 return -1;
1600 }
1601 buf_bak = ifc.ifc_buf;
1602 if (!LOS_IsUserAddress((VADDR_T)(uintptr_t)buf_bak)) {
1603 set_errno(EFAULT);
1604 return -1;
1605 }
1606 ifc.ifc_buf = malloc(nbytes);
1607 if (ifc.ifc_buf == NULL) {
1608 set_errno(ENOMEM);
1609 return -1;
1610 }
1611 (void)memset_s(ifc.ifc_buf, nbytes, 0, nbytes);
1612
1613 ret = lwip_ioctl(sockfd, cmd, &ifc);
1614 if (ret == 0) {
1615 if (LOS_ArchCopyToUser(buf_bak, ifc.ifc_buf, nbytes) != 0) {
1616 set_errno(EFAULT);
1617 ret = -1;
1618 }
1619 }
1620
1621 free(ifc.ifc_buf);
1622 ifc.ifc_buf = buf_bak;
1623 if (LOS_ArchCopyToUser(argp, &ifc, sizeof(struct ifconf)) != 0) {
1624 set_errno(EFAULT);
1625 ret = -1;
1626 }
1627 return ret;
1628 }
1629
1630 int socks_ioctl(int sockfd, long cmd, void *argp)
1631 {
1632 void *argpbak = argp;
1633 int ret;
1634 size_t nbytes = 0;
1635
1636 if (LOS_IsUserAddress((VADDR_T)(uintptr_t)argp)) {
1637 switch (cmd) {
1638 case FIONREAD:
1639 case FIONBIO:
1640 nbytes = sizeof(int);
1641 break;
1642 case SIOCADDRT:
1643 nbytes = sizeof(struct rtentry);
1644 break;
1645 case SIOCGIFCONF:
1646 return do_ioctl_SIOCGIFCONF(sockfd, cmd, argp);
1647 case SIOCSIPV6DAD:
1648 case SIOCGIPV6DAD:
1649 case SIOCSIPV6DPCTD:
1650 case SIOCGIPV6DPCTD:
1651 case SIOCGIFADDR:
1652 case SIOCSIFADDR:
1653 case SIOCDIFADDR:
1654 case SIOCGIFNETMASK:
1655 case SIOCSIFNETMASK:
1656 case SIOCSIFHWADDR:
1657 case SIOCGIFHWADDR:
1658 case SIOCSIFFLAGS:
1659 case SIOCGIFFLAGS:
1660 case SIOCGIFNAME:
1661 case SIOCSIFNAME:
1662 case SIOCGIFINDEX:
1663 case SIOCGIFMTU:
1664 case SIOCSIFMTU:
1665 case SIOCETHTOOL:
1666 case SIOCGIFBRDADDR:
1667 nbytes = sizeof(struct ifreq);
1668 break;
1669 default:
1670 nbytes = 0;
1671 }
1672 if (argp != NULL && nbytes > 0) {
1673 argp = malloc(nbytes);
1674 if (argp == NULL) {
1675 set_errno(ENOMEM);
1676 return -1;
1677 }
1678 if (LOS_ArchCopyFromUser(argp, argpbak, nbytes) != 0) {
1679 free(argp);
1680 set_errno(EFAULT);
1681 return -1;
1682 }
1683 }
1684 }
1685 ret = lwip_ioctl(sockfd, cmd, argp);
1686 if (ret == 0 && argp != argpbak) {
1687 if (LOS_ArchCopyToUser(argpbak, argp, nbytes) != 0) {
1688 /* how to rollback ioctl ? */
1689 set_errno(EFAULT);
1690 ret = -1;
1691 }
1692 }
1693 if (argp != argpbak) {
1694 free(argp);
1695 }
1696 return ret;
1697 }
1698
1699 void socks_refer(int sockfd)
1700 {
1701 struct lwip_sock *sock = NULL;
1702 SYS_ARCH_DECL_PROTECT(lev);
1703
1704 sock = get_socket(sockfd);
1705 if (!sock) {
1706 return;
1707 }
1708
1709 SYS_ARCH_PROTECT(lev);
1710
1711 sock->s_refcount++;
1712
1713 SYS_ARCH_UNPROTECT(lev);
1714
1715 done_socket(sock);
1716 }
1717
1718 int socks_close(int sockfd)
1719 {
1720 struct lwip_sock *sock = NULL;
1721 SYS_ARCH_DECL_PROTECT(lev);
1722
1723 sock = get_socket(sockfd);
1724 if (!sock) {
1725 return -1;
1726 }
1727
1728 SYS_ARCH_PROTECT(lev);
1729
1730 if (sock->s_refcount == 0) {
1731 SYS_ARCH_UNPROTECT(lev);
1732 done_socket(sock);
1733 return lwip_close(sockfd);
1734 }
1735
1736 sock->s_refcount--;
1737
1738 SYS_ARCH_UNPROTECT(lev);
1739 done_socket(sock);
1740 return 0;
1741 }
1742