• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2022-2022 Huawei Technologies Co., Ltd. All rights reserved.
3  *
4  * UniProton is licensed under Mulan PSL v2.
5  * You can use this software according to the terms and conditions of the Mulan PSL v2.
6  * You may obtain a copy of Mulan PSL v2 at:
7  *          http://license.coscl.org.cn/MulanPSL2
8  * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
9  * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
10  * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
11  * See the Mulan PSL v2 for more details.
12  * Create: 2022-09-21
13  * Description: 网络
14  */
15 
16 #include "lwip/sockets.h"
17 #include "lwip/priv/tcpip_priv.h"
18 #include "lwip/priv/sockets_priv.h"
19 #include "lwip/prot/dhcp.h"
20 #include "lwip/dhcp.h"
21 #include "lwip/if_api.h"
22 
23 #if !LWIP_COMPAT_SOCKETS
24 #if LWIP_SOCKET
25 
26 #define CHECK_NULL_PTR_RETURN(ptr) do { \
27     if ((ptr) == NULL) {                \
28         set_errno(EFAULT);              \
29         return -1;                      \
30     }                                   \
31 } while (0)
32 
accept(int s,struct sockaddr * addr,socklen_t * addrlen)33 int accept(int s, struct sockaddr *addr, socklen_t *addrlen)
34 {
35     return lwip_accept(s, addr, addrlen);
36 }
37 
bind(int s,const struct sockaddr * name,socklen_t namelen)38 int bind(int s, const struct sockaddr *name, socklen_t namelen)
39 {
40     CHECK_NULL_PTR_RETURN(name);
41     if (namelen < sizeof(*name)) {
42         set_errno(EINVAL);
43         return -1;
44     }
45     return lwip_bind(s, name, namelen);
46 }
47 
shutdown(int s,int how)48 int shutdown(int s, int how)
49 {
50     return lwip_shutdown(s, how);
51 }
52 
getpeername(int s,struct sockaddr * name,socklen_t * namelen)53 int getpeername(int s, struct sockaddr *name, socklen_t *namelen)
54 {
55     CHECK_NULL_PTR_RETURN(name);
56     CHECK_NULL_PTR_RETURN(namelen);
57     return lwip_getpeername(s, name, namelen);
58 }
59 
getsockname(int s,struct sockaddr * name,socklen_t * namelen)60 int getsockname(int s, struct sockaddr *name, socklen_t *namelen)
61 {
62     CHECK_NULL_PTR_RETURN(name);
63     CHECK_NULL_PTR_RETURN(namelen);
64     return lwip_getsockname(s, name, namelen);
65 }
66 
getsockopt(int s,int level,int optname,void * optval,socklen_t * optlen)67 int getsockopt(int s, int level, int optname, void *optval, socklen_t *optlen)
68 {
69     CHECK_NULL_PTR_RETURN(optval);
70     return lwip_getsockopt(s, level, optname, optval, optlen);
71 }
72 
setsockopt(int s,int level,int optname,const void * optval,socklen_t optlen)73 int setsockopt(int s, int level, int optname, const void *optval, socklen_t optlen)
74 {
75     CHECK_NULL_PTR_RETURN(optval);
76     return lwip_setsockopt(s, level, optname, optval, optlen);
77 }
78 
closesocket(int s)79 int closesocket(int s)
80 {
81     return lwip_close(s);
82 }
83 
connect(int s,const struct sockaddr * name,socklen_t namelen)84 int connect(int s, const struct sockaddr *name, socklen_t namelen)
85 {
86     CHECK_NULL_PTR_RETURN(name);
87     if (namelen < sizeof(*name)) {
88         set_errno(EINVAL);
89         return -1;
90     }
91     return lwip_connect(s, name, namelen);
92 }
93 
listen(int s,int backlog)94 int listen(int s, int backlog)
95 {
96     if (backlog < 0) {
97         set_errno(EINVAL);
98         return -1;
99     }
100     return lwip_listen(s, backlog);
101 }
102 
recv(int s,void * mem,size_t len,int flags)103 ssize_t recv(int s, void *mem, size_t len, int flags)
104 {
105     CHECK_NULL_PTR_RETURN(mem);
106     return lwip_recv(s, mem, len, flags);
107 }
108 
recvfrom(int s,void * mem,size_t len,int flags,struct sockaddr * from,socklen_t * fromlen)109 ssize_t recvfrom(int s, void *mem, size_t len, int flags,
110                              struct sockaddr *from, socklen_t *fromlen)
111 {
112     CHECK_NULL_PTR_RETURN(mem);
113     return lwip_recvfrom(s, mem, len, flags, from, fromlen);
114 }
115 
recvmsg(int s,struct msghdr * message,int flags)116 ssize_t recvmsg(int s, struct msghdr *message, int flags)
117 {
118     CHECK_NULL_PTR_RETURN(message);
119     if (message->msg_iovlen) {
120         CHECK_NULL_PTR_RETURN(message->msg_iov);
121     }
122     return lwip_recvmsg(s, message, flags);
123 }
124 
send(int s,const void * dataptr,size_t size,int flags)125 ssize_t send(int s, const void *dataptr, size_t size, int flags)
126 {
127     CHECK_NULL_PTR_RETURN(dataptr);
128     return  lwip_send(s, dataptr, size, flags);
129 }
130 
sendmsg(int s,const struct msghdr * message,int flags)131 ssize_t sendmsg(int s, const struct msghdr *message, int flags)
132 {
133     CHECK_NULL_PTR_RETURN(message);
134     return lwip_sendmsg(s, message, flags);
135 }
136 
sendto(int s,const void * dataptr,size_t size,int flags,const struct sockaddr * to,socklen_t tolen)137 ssize_t sendto(int s, const void *dataptr, size_t size, int flags,
138                            const struct sockaddr *to, socklen_t tolen)
139 {
140     CHECK_NULL_PTR_RETURN(dataptr);
141     if (to && tolen < sizeof(*to)) {
142         set_errno(EINVAL);
143         return -1;
144     }
145     return lwip_sendto(s, dataptr, size, flags, to, tolen);
146 }
147 
socket(int domain,int type,int protocol)148 int socket(int domain, int type, int protocol)
149 {
150     return lwip_socket(domain, type, protocol);
151 }
152 
inet_ntop(int af,const void * src,char * dst,socklen_t size)153 const char *inet_ntop(int af, const void *src, char *dst, socklen_t size)
154 {
155     return lwip_inet_ntop(af, src, dst, size);
156 }
157 
inet_pton(int af,const char * src,void * dst)158 int inet_pton(int af, const char *src, void *dst)
159 {
160     return lwip_inet_pton(af, src, dst);
161 }
162 
163 #ifndef LWIP_INET_ADDR_FUNC
inet_addr(const char * cp)164 in_addr_t inet_addr(const char *cp)
165 {
166     return ipaddr_addr(cp);
167 }
168 #endif
169 
170 #ifndef LWIP_INET_NTOA_FUNC
inet_ntoa(struct in_addr addr)171 char *inet_ntoa(struct in_addr addr)
172 {
173     return ip4addr_ntoa((const ip4_addr_t*)&(addr));
174 }
175 #endif
176 
177 #ifndef LWIP_INET_ATON_FUNC
inet_aton(const char * cp,struct in_addr * addr)178 int inet_aton(const char *cp, struct in_addr *addr)
179 {
180     return ip4addr_aton(cp, (ip4_addr_t*)addr);
181 }
182 #endif
183 
ioctlsocket(int s,long cmd,void * argp)184 int ioctlsocket(int s, long cmd, void *argp)
185 {
186     return lwip_ioctl(s, cmd, argp);
187 }
188 
189 #ifdef LWIP_SOCKET_READ_FUNC
read(int fd,void * buf,size_t len)190 ssize_t read(int fd, void *buf, size_t len)
191 {
192     return lwip_read(fd, buf, len);
193 }
194 #endif
195 
196 #ifdef LWIP_SOCKET_WRITE_FUNC
write(int fd,const void * buf,size_t len)197 ssize_t write(int fd, const void *buf, size_t len)
198 {
199     return lwip_write(fd, buf, len);
200 }
201 #endif
202 
203 #ifdef LWIP_SOCKET_CLOSE_FUNC
close(int fd)204 int close(int fd)
205 {
206     return lwip_close(fd);
207 }
208 #endif
209 
210 #ifdef LWIP_SOCKET_IOCTL_FUNC
ioctl(int fd,int req,...)211 int ioctl(int fd, int req, ...)
212 {
213     UINTPTR arg = 0;
214     va_list ap;
215     va_start(ap, req);
216     arg = va_arg(ap, UINTPTR);
217     va_end(ap);
218     return lwip_ioctl(fd, (long)req, (void *)arg);
219 }
220 #endif
221 
222 #ifdef LWIP_SOCKET_FCNTL_FUNC
fcntl(int fd,int cmd,...)223 int fcntl(int fd, int cmd, ...)
224 {
225     int val = 0;
226     va_list ap;
227     va_start(ap, cmd);
228     val = va_arg(ap, int);
229     va_end(ap);
230     return lwip_fcntl(fd, cmd, val);
231 }
232 #endif
233 
234 #if LWIP_SOCKET_SELECT
235 #ifdef LWIP_SOCKET_SELECT_FUNC
select(int maxfdp1,fd_set * readset,fd_set * writeset,fd_set * exceptset,struct timeval * timeout)236 int select(int maxfdp1, fd_set *readset, fd_set *writeset, fd_set *exceptset, struct timeval *timeout)
237 {
238     return lwip_select(maxfdp1, readset, writeset, exceptset, timeout);
239 }
240 #endif
241 #endif
242 
243 #if LWIP_SOCKET_POLL
244 #ifdef LWIP_SOCKET_POLL_FUNC
poll(struct pollfd * fds,nfds_t nfds,int timeout)245 int poll(struct pollfd *fds, nfds_t nfds, int timeout)
246 {
247     return lwip_poll(fds, nfds, timeout);
248 }
249 #endif
250 #endif
251 
if_nametoindex(const char * ifname)252 unsigned int if_nametoindex(const char *ifname)
253 {
254     return lwip_if_nametoindex(ifname);
255 }
256 
257 #endif
258 #endif /* !LWIP_COMPAT_SOCKETS */
259 
260 struct lwip_ioctl_apimsg {
261     struct tcpip_api_call_data call;
262     struct lwip_sock *sock;
263     long cmd;
264     void *argp;
265 };
266 
267 static err_t OsLwipDoIoctlImpl(struct tcpip_api_call_data *call);
268 
269 #define IOCTL_CMD_CASE_HANDLER() do {                      \
270     err_t  err;                                            \
271     struct lwip_ioctl_apimsg msg;                          \
272     msg.sock = sock;                                       \
273     msg.cmd = cmd;                                         \
274     msg.argp = argp;                                       \
275                                                            \
276     err = tcpip_api_call(OsLwipDoIoctlImpl, &msg.call);    \
277     if (err != ENOSYS) {                                   \
278         sock_set_errno(sock, err);                         \
279         done_socket(sock);                                 \
280         return -(err != ERR_OK);                           \
281     }                                                      \
282 } while (0)
283 
284 #include "../api/sockets.c"
285 
OsLwipIoctlInternalSiocgifConf(struct ifreq * ifr)286 static u8_t OsLwipIoctlInternalSiocgifConf(struct ifreq *ifr)
287 {
288     struct netif *netif = NULL;
289     struct ifreq ifreq;
290     struct sockaddr_in *sockIn = NULL;
291     S32 ret;
292 
293     /* Format the caller's buffer. */
294     struct ifconf *ifc = (struct ifconf *)ifr;
295     S32 len = ifc->ifc_len;
296 
297     /* Loop over the interfaces, and write an info block for each. */
298     S32 pos = 0;
299     for (netif = netif_list; netif != NULL; netif = netif->next) {
300         if (ifc->ifc_buf == NULL) {
301             pos = (pos + (int)sizeof(struct ifreq));
302             continue;
303         }
304 
305         if (len < (S32)sizeof(ifreq)) {
306             break;
307         }
308         if (memset_s(&ifreq, sizeof(struct ifreq), 0, sizeof(struct ifreq)) != EOK) {
309             return EBADF;
310         }
311         if (netif->link_layer_type == LOOPBACK_IF) {
312             ret = snprintf_s(ifreq.ifr_name, IFNAMSIZ, (IFNAMSIZ - 1), "%.2s", netif->name);
313             if ((ret <= 0) || (ret >= IFNAMSIZ)) {
314                 LWIP_DEBUGF(NETIF_DEBUG, ("lwip_ioctl: snprintf_s ifr_name failed."));
315                 return ENOBUFS;
316             }
317         } else {
318             ret = snprintf_s(ifreq.ifr_name, IFNAMSIZ, (IFNAMSIZ - 1), "%s", netif_get_name(netif));
319             if ((ret <= 0) || (ret >= IFNAMSIZ)) {
320                 LWIP_DEBUGF(NETIF_DEBUG, ("lwip_ioctl: snprintf_s ifr_name failed."));
321                 return ENOBUFS;
322             }
323         }
324 
325         sockIn = (struct sockaddr_in *)&ifreq.ifr_addr;
326         sockIn->sin_family = AF_INET;
327         sockIn->sin_addr.s_addr = ip_2_ip4(&netif->ip_addr)->addr;
328         if (memcpy_s(ifc->ifc_buf + pos, sizeof(struct ifreq), &ifreq, sizeof(struct ifreq)) != EOK) {
329             return ENOBUFS;
330         }
331         pos = pos + (int)sizeof(struct ifreq);
332         len = len - (int)sizeof(struct ifreq);
333     }
334 
335     ifc->ifc_len = pos;
336     return 0;
337 }
338 
OsLwipIoctlInternalSiocgifAddr(struct ifreq * ifr)339 static u8_t OsLwipIoctlInternalSiocgifAddr(struct ifreq *ifr)
340 {
341     struct sockaddr_in *sockIn = NULL;
342 
343     /* get netif ipaddr */
344     struct netif *netif = netif_find(ifr->ifr_name);
345     if (netif == NULL) {
346         return ENODEV;
347     }
348     sockIn = (struct sockaddr_in *)&ifr->ifr_addr;
349     sockIn->sin_family = AF_INET;
350     sockIn->sin_addr.s_addr = ip_2_ip4(&netif->ip_addr)->addr;
351     return 0;
352 }
353 
OsLwipIoctlInternalSiocgifNetmask(struct ifreq * ifr)354 static u8_t OsLwipIoctlInternalSiocgifNetmask(struct ifreq *ifr)
355 {
356     struct sockaddr_in *sockIn = NULL;
357 
358     /* get netif netmask */
359     struct netif *netif = netif_find(ifr->ifr_name);
360     if (netif == NULL) {
361         return ENODEV;
362     }
363     sockIn = (struct sockaddr_in *)&ifr->ifr_netmask;
364     sockIn->sin_family = AF_INET;
365     sockIn->sin_addr.s_addr = ip_2_ip4(&netif->netmask)->addr;
366     return 0;
367 }
368 
OsLwipIoctlInternalSiocgifHwAddr(struct ifreq * ifr)369 static u8_t OsLwipIoctlInternalSiocgifHwAddr(struct ifreq *ifr)
370 {
371     /* get netif hw addr */
372     struct netif *netif = netif_find(ifr->ifr_name);
373     if (netif == NULL) {
374         return ENODEV;
375     }
376 
377 #if LWIP_HAVE_LOOPIF
378     if (netif->link_layer_type == LOOPBACK_IF) {
379         return EPERM;
380     }
381 #endif /* LWIP_HAVE_LOOPIF */
382 
383     if (memcpy_s((void *)ifr->ifr_hwaddr.sa_data, sizeof(ifr->ifr_hwaddr.sa_data),
384                  (void *)netif->hwaddr, netif->hwaddr_len) != EOK) {
385         return EINVAL;
386     }
387     return 0;
388 }
389 
OsLwipIoctlInternalSiocsifFlags(struct ifreq * ifr)390 static u8_t OsLwipIoctlInternalSiocsifFlags(struct ifreq *ifr)
391 {
392     /* set netif hw addr */
393     struct netif *netif = netif_find(ifr->ifr_name);
394     if (netif == NULL) {
395         return ENODEV;
396     }
397 
398 #if LWIP_HAVE_LOOPIF
399     if (netif->link_layer_type == LOOPBACK_IF) {
400         return EPERM;
401     }
402 #endif /* LWIP_HAVE_LOOPIF */
403 
404     if (((unsigned short)ifr->ifr_flags & IFF_UP) && !(netif->flags & NETIF_FLAG_UP)) {
405         (void)netif_set_up(netif);
406     } else if (!((unsigned short)ifr->ifr_flags & IFF_UP) && (netif->flags & NETIF_FLAG_UP)) {
407         (void)netif_set_down(netif);
408     }
409     if (((unsigned short)ifr->ifr_flags & IFF_RUNNING) && !(netif->flags & NETIF_FLAG_LINK_UP)) {
410         (void)netif_set_link_up(netif);
411     } else if (!((unsigned short)ifr->ifr_flags & IFF_RUNNING) && (netif->flags & NETIF_FLAG_LINK_UP)) {
412         (void)netif_set_link_down(netif);
413     }
414 
415     if ((unsigned short)ifr->ifr_flags & IFF_BROADCAST) {
416         netif->flags |= NETIF_FLAG_BROADCAST;
417     } else {
418         netif->flags = netif->flags & (~NETIF_FLAG_BROADCAST);
419     }
420     if ((unsigned short)ifr->ifr_flags & IFF_NOARP) {
421         netif->flags = (netif->flags & (~NETIF_FLAG_ETHARP));
422     } else {
423         netif->flags |= NETIF_FLAG_ETHARP;
424     }
425 
426     if ((unsigned short)ifr->ifr_flags & IFF_MULTICAST) {
427 #if LWIP_IGMP
428         netif->flags |= NETIF_FLAG_IGMP;
429 #endif /* LWIP_IGMP */
430 #if LWIP_IPV6 && LWIP_IPV6_MLD
431         netif->flags |= NETIF_FLAG_MLD6;
432 #endif /* LWIP_IPV6_MLD */
433     } else {
434 #if LWIP_IGMP
435         netif->flags = (netif->flags & ~NETIF_FLAG_IGMP);
436 #endif /* LWIP_IGMP */
437 #if LWIP_IPV6 && LWIP_IPV6_MLD
438         netif->flags = (netif->flags & ~NETIF_FLAG_MLD6);
439 #endif /* LWIP_IPV6_MLD */
440     }
441 
442 #if LWIP_DHCP
443     if ((unsigned short)ifr->ifr_flags & IFF_DYNAMIC) {
444         (void)dhcp_start(netif);
445     } else {
446         dhcp_stop(netif);
447 #if !LWIP_DHCP_SUBSTITUTE
448         dhcp_cleanup(netif);
449 #endif
450     }
451 #endif
452 
453 #if LWIP_NETIF_PROMISC
454     if (((unsigned short)ifr->ifr_flags & IFF_PROMISC)) {
455         netif->flags |= NETIF_FLAG_PROMISC;
456     } else {
457         netif->flags &= ~NETIF_FLAG_PROMISC;
458     }
459     if (netif->drv_config) {
460         netif->drv_config(netif, IFF_PROMISC, !!((unsigned short)ifr->ifr_flags & IFF_PROMISC));
461     }
462 #endif /* LWIP_NETIF_PROMISC */
463     return 0;
464 }
465 
OsLwipIoctlInternalSiocgifFlags(struct ifreq * ifr)466 static u8_t OsLwipIoctlInternalSiocgifFlags(struct ifreq *ifr)
467 {
468     /* set netif hw addr */
469     struct netif *netif = netif_find(ifr->ifr_name);
470     if (netif == NULL) {
471         return ENODEV;
472     } else {
473         if (netif->flags & NETIF_FLAG_UP) {
474             ifr->ifr_flags = ((unsigned short)(ifr->ifr_flags)) | IFF_UP;
475         } else {
476             ifr->ifr_flags = ((unsigned short)(ifr->ifr_flags)) & ~IFF_UP;
477         }
478         if (netif->flags & NETIF_FLAG_LINK_UP) {
479             ifr->ifr_flags = ((unsigned short)(ifr->ifr_flags)) | IFF_RUNNING;
480         } else {
481             ifr->ifr_flags = ((unsigned short)(ifr->ifr_flags)) & ~IFF_RUNNING;
482         }
483         if (netif->flags & NETIF_FLAG_BROADCAST) {
484             ifr->ifr_flags = ((unsigned short)(ifr->ifr_flags)) | IFF_BROADCAST;
485         } else {
486             ifr->ifr_flags = ((unsigned short)(ifr->ifr_flags)) & ~IFF_BROADCAST;
487         }
488         if (netif->flags & NETIF_FLAG_ETHARP) {
489             ifr->ifr_flags = ((unsigned short)(ifr->ifr_flags)) & ~IFF_NOARP;
490         } else {
491             ifr->ifr_flags = ((unsigned short)(ifr->ifr_flags)) | IFF_NOARP;
492         }
493 
494 #if LWIP_IGMP || LWIP_IPV6_MLD
495         if (
496 #if LWIP_IGMP
497             (netif->flags & NETIF_FLAG_IGMP)
498 #endif /* LWIP_IGMP */
499 #if LWIP_IGMP && LWIP_IPV6_MLD
500             ||
501 #endif /* LWIP_IGMP && LWIP_IPV6_MLD */
502 #if LWIP_IPV6_MLD
503             (netif->flags & NETIF_FLAG_MLD6)
504 #endif /* LWIP_IPV6_MLD */
505                 ) {
506             ifr->ifr_flags = (short)((unsigned short)ifr->ifr_flags | IFF_MULTICAST);
507         } else {
508             ifr->ifr_flags = (short)((unsigned short)ifr->ifr_flags & (~IFF_MULTICAST));
509         }
510 #endif /* LWIP_IGMP || LWIP_IPV6_MLD */
511 
512 #if LWIP_DHCP
513         if (dhcp_supplied_address(netif)) {
514             ifr->ifr_flags = (short)((unsigned short)ifr->ifr_flags | IFF_DYNAMIC);
515         } else {
516             ifr->ifr_flags = (short)((unsigned short)ifr->ifr_flags & (~IFF_DYNAMIC));
517         }
518 #endif
519 
520 #if LWIP_HAVE_LOOPIF
521         if (netif->link_layer_type == LOOPBACK_IF) {
522             ifr->ifr_flags = ((unsigned short)(ifr->ifr_flags)) | IFF_LOOPBACK;
523         }
524 #endif
525 
526 #if LWIP_NETIF_PROMISC
527         if (netif->flags & NETIF_FLAG_PROMISC) {
528             ifr->ifr_flags = ((unsigned short)(ifr->ifr_flags)) | IFF_PROMISC;
529         } else {
530             ifr->ifr_flags = ((unsigned short)(ifr->ifr_flags)) & ~IFF_PROMISC;
531         }
532 #endif /* LWIP_NETIF_PROMISC */
533 
534         return 0;
535     }
536 }
537 
OsLwipIoctlInternalSiocgifName(struct ifreq * ifr)538 static u8_t OsLwipIoctlInternalSiocgifName(struct ifreq *ifr)
539 {
540     struct netif *netif = NULL;
541     int ret;
542 
543     for (netif = netif_list; netif != NULL; netif = netif->next) {
544         if (ifr->ifr_ifindex == netif_get_index(netif)) {
545             break;
546         }
547     }
548 
549     if (netif == NULL) {
550         return ENODEV;
551     } else {
552         if (netif->link_layer_type == LOOPBACK_IF) {
553             ret = snprintf_s(ifr->ifr_name, IFNAMSIZ, (IFNAMSIZ - 1), "%.2s", netif->name);
554             if ((ret <= 0) || (ret >= IFNAMSIZ)) {
555                 return ENOBUFS;
556             }
557         } else {
558             ret = snprintf_s(ifr->ifr_name, IFNAMSIZ, (IFNAMSIZ - 1), "%s", netif_get_name(netif));
559             if ((ret <= 0) || (ret >= IFNAMSIZ)) {
560                 return ENOBUFS;
561             }
562         }
563         return 0;
564     }
565 }
566 
OsLwipValidateIfname(const char * name,u8_t * letPos)567 static u8_t OsLwipValidateIfname(const char *name, u8_t *letPos)
568 {
569     U16 numPos = 0;
570     U16 letterPos = 0;
571     U16 pos = 0;
572     u8_t haveNum = 0;
573 
574     /* if the first position of variable name is not letter, such as '6eth2' */
575     if (!((*name >= 'a' && *name <= 'z') || (*name >= 'A' && *name <= 'Z'))) {
576         return 0;
577     }
578 
579     /* check if the position of letter is bigger than the the position of digital */
580     while (*name != '\0') {
581         if ((*name >= '0') && (*name <= '9')) {
582             numPos = pos;
583             haveNum = 1;
584         } else if (((*name >= 'a') && (*name <= 'z')) || ((*name >= 'A') && (*name <= 'Z'))) {
585             letterPos = pos;
586             if (haveNum != 0) {
587                 return 0;
588             }
589         } else {
590             return 0;
591         }
592         pos++;
593         name++;
594     }
595 
596     /* for the speacil case as all position of variable name is letter, such as 'ethabc' */
597     if (numPos == 0) {
598         return 0;
599     }
600 
601     /* cheak if the digital in the variable name is bigger than 255, such as 'eth266' */
602     if (atoi(name - (pos - letterPos - 1)) > 255) {
603         return 0;
604     }
605 
606     *letPos = (u8_t)letterPos;
607     return 1;
608 }
609 
OsLwipIoctlInternalSiocsifName(struct ifreq * ifr)610 static u8_t OsLwipIoctlInternalSiocsifName(struct ifreq *ifr)
611 {
612     u8_t letterPos = 0;
613     struct netif *netif = netif_find(ifr->ifr_name);
614     if (netif == NULL) {
615         return ENODEV;
616     } else if (netif->link_layer_type == LOOPBACK_IF) {
617         return EPERM;
618     } else if ((netif->flags & IFF_UP) != 0) {
619         return EBUSY;
620     } else {
621         if (strncmp(ifr->ifr_name, ifr->ifr_newname, IFNAMSIZ) == 0) {
622             /* not change */
623             return 0;
624         }
625 
626         ifr->ifr_newname[IFNAMSIZ - 1] = '\0';
627         if ((OsLwipValidateIfname(ifr->ifr_newname, &letterPos) == 0) || (strlen(ifr->ifr_newname) > (IFNAMSIZ - 1))) {
628             return EINVAL;
629         }
630 
631         if (strncpy_s(netif->full_name, sizeof(netif->full_name), ifr->ifr_newname, strlen(ifr->ifr_newname)) != EOK) {
632             return EINVAL;
633         }
634     }
635 
636     return 0;
637 }
638 
OsLwipIoctlInternalSiocgifIndex(struct ifreq * ifr)639 static u8_t OsLwipIoctlInternalSiocgifIndex(struct ifreq *ifr)
640 {
641     struct netif *netif = netif_find(ifr->ifr_name);
642     if (netif == NULL) {
643         return ENODEV;
644     } else {
645         ifr->ifr_ifindex = netif_get_index(netif);
646         return 0;
647     }
648 }
649 
OsLwipIoctlInternalSiocgifMtu(struct ifreq * ifr)650 static u8_t OsLwipIoctlInternalSiocgifMtu(struct ifreq *ifr)
651 {
652     /* get netif hw addr */
653     struct netif *netif = netif_find(ifr->ifr_name);
654     if (netif == NULL) {
655         return ENODEV;
656     } else {
657         ifr->ifr_mtu = netif->mtu;
658         return 0;
659     }
660 }
661 
OsLwipIoctlInternalSiocgifBrdAddr(struct ifreq * ifr)662 static u8_t OsLwipIoctlInternalSiocgifBrdAddr(struct ifreq *ifr)
663 {
664     struct sockaddr_in *sockIn = NULL;
665 
666     /* get netif subnet broadcast addr */
667     struct netif *netif = netif_find(ifr->ifr_name);
668     if (netif == NULL) {
669         return ENODEV;
670     }
671     if (ip4_addr_isany_val(*(ip_2_ip4(&netif->netmask)))) {
672         return ENXIO;
673     }
674     sockIn = (struct sockaddr_in *)&ifr->ifr_addr;
675     sockIn->sin_family = AF_INET;
676     sockIn->sin_addr.s_addr = (ip_2_ip4(&((netif)->ip_addr))->addr | ~(ip_2_ip4(&netif->netmask)->addr));
677     return 0;
678 }
679 
OsLwipIoctlImpl(const struct lwip_sock * sock,long cmd,void * argp)680 static u8_t OsLwipIoctlImpl(const struct lwip_sock *sock, long cmd, void *argp)
681 {
682     u8_t err = EINVAL;
683     struct ifreq *ifr = (struct ifreq *)argp;
684 
685     /* allow it only on IPv6 sockets... */
686     u8_t isIpv6 = NETCONNTYPE_ISIPV6((unsigned int)(sock->conn->type));
687 
688     switch ((u32_t)cmd) {
689         case SIOCGIFCONF:
690             if (isIpv6 == 0) {
691                 err = OsLwipIoctlInternalSiocgifConf(ifr);
692             }
693             break;
694         case SIOCGIFADDR:
695             if (isIpv6 == 0) {
696                 err = OsLwipIoctlInternalSiocgifAddr(ifr);
697             }
698             break;
699         case SIOCGIFNETMASK:
700             if (isIpv6 == 0) {
701                 err = OsLwipIoctlInternalSiocgifNetmask(ifr);
702             }
703             break;
704         case SIOCGIFHWADDR:
705             err = OsLwipIoctlInternalSiocgifHwAddr(ifr);
706             break;
707         case SIOCSIFFLAGS:
708             err = OsLwipIoctlInternalSiocsifFlags(ifr);
709             break;
710         case SIOCGIFFLAGS:
711             err = OsLwipIoctlInternalSiocgifFlags(ifr);
712             break;
713         case SIOCGIFNAME:
714             err = OsLwipIoctlInternalSiocgifName(ifr);
715             break;
716         case SIOCSIFNAME:
717             err = OsLwipIoctlInternalSiocsifName(ifr);
718             break;
719         case SIOCGIFINDEX:
720             err = OsLwipIoctlInternalSiocgifIndex(ifr);
721             break;
722         case SIOCGIFMTU:
723             err = OsLwipIoctlInternalSiocgifMtu(ifr);
724             break;
725         case SIOCGIFBRDADDR:
726             if (isIpv6 == 0) {
727                 err = OsLwipIoctlInternalSiocgifBrdAddr(ifr);
728             }
729             break;
730         default:
731             err = ENOSYS;
732             LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_ioctl(UNIMPL: 0x%lx)\n", cmd));
733             break;
734     }
735 
736     return err;
737 }
738 
OsLwipDoIoctlImpl(struct tcpip_api_call_data * call)739 static err_t OsLwipDoIoctlImpl(struct tcpip_api_call_data *call)
740 {
741     struct lwip_ioctl_apimsg *msg = (struct lwip_ioctl_apimsg *)(void *)call;
742     return OsLwipIoctlImpl(msg->sock, msg->cmd, msg->argp);
743 }
744