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