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