1 /*
2 * Copyright (c) 2006-2023, RT-Thread Development Team
3 *
4 * SPDX-License-Identifier: Apache-2.0
5 *
6 * Change Logs:
7 * Date Author Notes
8 * 2019-03-18 ChenYong First version
9 * 2025-01-04 Evlers add statistics and more inupt parameters to ping command
10 */
11
12 #include <stdio.h>
13 #include <string.h>
14 #include <stdlib.h>
15
16 #include <rtthread.h>
17 #include <rthw.h>
18
19 #include <netdev_ipaddr.h>
20 #include <netdev.h>
21
22 #ifdef RT_USING_SAL
23 #include <sal_netdb.h>
24 #include <sal_low_lvl.h>
25 #endif /* RT_USING_SAL */
26
27 #define DBG_TAG "netdev"
28 #define DBG_LVL DBG_INFO
29 #include <rtdbg.h>
30
31 #if defined(SAL_USING_AF_NETLINK)
32 #include <route_netlink.h>
33 #endif
34
35 /* The list of network interface device */
36 struct netdev *netdev_list = RT_NULL;
37 /* The default network interface device */
38 struct netdev *netdev_default = RT_NULL;
39 /* The global network register callback */
40 static netdev_callback_fn g_netdev_register_callback = RT_NULL;
41 static netdev_callback_fn g_netdev_default_change_callback = RT_NULL;
42 static RT_DEFINE_SPINLOCK(_spinlock);
43 static int netdev_num;
44
45 /**
46 * This function will register network interface device and
47 * add it to network interface device list.
48 *
49 * @param netdev the network interface device object
50 * @param name the network interface device name
51 * @param user_data user-specific data
52 *
53 * @return 0: registered successfully
54 * -1: registered failed
55 */
netdev_register(struct netdev * netdev,const char * name,void * user_data)56 int netdev_register(struct netdev *netdev, const char *name, void *user_data)
57 {
58 rt_uint16_t flags_mask;
59 rt_uint16_t index;
60
61 RT_ASSERT(netdev);
62 RT_ASSERT(name);
63
64 /* clean network interface device */
65 flags_mask = NETDEV_FLAG_UP | NETDEV_FLAG_LINK_UP | NETDEV_FLAG_INTERNET_UP | NETDEV_FLAG_DHCP;
66 netdev->flags &= ~flags_mask;
67
68 ip_addr_set_zero(&(netdev->ip_addr));
69 ip_addr_set_zero(&(netdev->netmask));
70 ip_addr_set_zero(&(netdev->gw));
71
72 IP_SET_TYPE_VAL(netdev->ip_addr, IPADDR_TYPE_V4);
73 IP_SET_TYPE_VAL(netdev->netmask, IPADDR_TYPE_V4);
74 IP_SET_TYPE_VAL(netdev->gw, IPADDR_TYPE_V4);
75 #if NETDEV_IPV6
76 for (index = 0; index < NETDEV_IPV6_NUM_ADDRESSES; index++)
77 {
78 ip_addr_set_zero(&(netdev->ip6_addr[index]));
79 IP_SET_TYPE_VAL(netdev->ip_addr, IPADDR_TYPE_V6);
80 }
81 #endif /* NETDEV_IPV6 */
82 for (index = 0; index < NETDEV_DNS_SERVERS_NUM; index++)
83 {
84 ip_addr_set_zero(&(netdev->dns_servers[index]));
85 IP_SET_TYPE_VAL(netdev->ip_addr, IPADDR_TYPE_V4);
86 }
87 netdev->status_callback = RT_NULL;
88 netdev->addr_callback = RT_NULL;
89
90 if(rt_strlen(name) > RT_NAME_MAX)
91 {
92 char netdev_name[RT_NAME_MAX + 1] = {0};
93
94 rt_strncpy(netdev_name, name, RT_NAME_MAX);
95 LOG_E("netdev name[%s] length is so long that have been cut into [%s].", name, netdev_name);
96 }
97
98 /* fill network interface device */
99 rt_strncpy(netdev->name, name, RT_NAME_MAX);
100 netdev->user_data = user_data;
101
102 /* initialize current network interface device single list */
103 rt_slist_init(&(netdev->list));
104
105 rt_spin_lock(&_spinlock);
106
107 if (netdev_list == RT_NULL)
108 {
109 netdev_list = netdev;
110 }
111 else
112 {
113 /* tail insertion */
114 rt_slist_append(&(netdev_list->list), &(netdev->list));
115 }
116
117 netdev_num++;
118 netdev->ifindex = netdev_num;
119
120 rt_spin_unlock(&_spinlock);
121
122 if (netdev_default == RT_NULL)
123 {
124 netdev_set_default(netdev_list);
125 }
126
127 /* execute netdev register callback */
128 if (g_netdev_register_callback)
129 {
130 g_netdev_register_callback(netdev, NETDEV_CB_REGISTER);
131 }
132
133 #if defined(SAL_USING_AF_NETLINK)
134 rtnl_ip_notify(netdev, RTM_NEWLINK);
135 #endif
136
137 return RT_EOK;
138 }
139
140 /**
141 * This function will unregister network interface device and
142 * delete it from network interface device list.
143 *
144 * @param netdev the network interface device object
145 *
146 * @return 0: unregistered successfully
147 * -1: unregistered failed
148 */
netdev_unregister(struct netdev * netdev)149 int netdev_unregister(struct netdev *netdev)
150 {
151 rt_slist_t *node = RT_NULL;
152 struct netdev *cur_netdev = RT_NULL;
153
154 RT_ASSERT(netdev);
155
156 if (netdev_list == RT_NULL)
157 {
158 return -RT_ERROR;
159 }
160
161 rt_spin_lock(&_spinlock);
162
163 for (node = &(netdev_list->list); node; node = rt_slist_next(node))
164 {
165 cur_netdev = rt_slist_entry(node, struct netdev, list);
166 if (cur_netdev == netdev)
167 {
168 /* find this network interface device in network interface device list */
169 if (netdev_list == netdev)
170 {
171 rt_slist_t *next = rt_slist_next(node);
172 if (next)
173 {
174 netdev_list = rt_slist_entry(next, struct netdev, list);
175 }
176 else
177 {
178 netdev_list = RT_NULL;
179 }
180 }
181 else
182 {
183 rt_slist_remove(&(netdev_list->list), &(cur_netdev->list));
184 }
185 if (netdev_default == netdev)
186 {
187 netdev_default = RT_NULL;
188 }
189 break;
190 }
191 }
192 rt_spin_unlock(&_spinlock);
193
194 #if defined(SAL_USING_AF_NETLINK)
195 rtnl_ip_notify(netdev, RTM_DELLINK);
196 #endif
197
198 if (netdev_default == RT_NULL)
199 {
200 netdev_set_default(netdev_list);
201 }
202
203 if (cur_netdev == netdev)
204 {
205 #ifdef RT_USING_SAL
206 extern int sal_netdev_cleanup(struct netdev *netdev);
207 sal_netdev_cleanup(netdev);
208 #endif
209 rt_memset(netdev, 0, sizeof(*netdev));
210 }
211
212 return -RT_ERROR;
213 }
214
215 /**
216 * This function will set register callback
217 *
218 * @param register_callback the network register callback
219 *
220 */
netdev_set_register_callback(netdev_callback_fn register_callback)221 void netdev_set_register_callback(netdev_callback_fn register_callback)
222 {
223 g_netdev_register_callback = register_callback;
224 }
225
226 /**
227 * This function will get the first network interface device
228 * with the flags in network interface device list.
229 *
230 * @param flags the network interface device flags
231 *
232 * @return != NULL: network interface device object
233 * NULL: get failed
234 */
netdev_get_first_by_flags(uint16_t flags)235 struct netdev *netdev_get_first_by_flags(uint16_t flags)
236 {
237 rt_slist_t *node = RT_NULL;
238 struct netdev *netdev = RT_NULL;
239
240 if (netdev_list == RT_NULL)
241 {
242 return RT_NULL;
243 }
244
245 rt_spin_lock(&_spinlock);
246
247 for (node = &(netdev_list->list); node; node = rt_slist_next(node))
248 {
249 netdev = rt_slist_entry(node, struct netdev, list);
250 if (netdev && (netdev->flags & flags) != 0)
251 {
252 rt_spin_unlock(&_spinlock);
253 return netdev;
254 }
255 }
256
257 rt_spin_unlock(&_spinlock);
258
259 return RT_NULL;
260 }
261
262 /**
263 * This function will get the first network interface device
264 * in network interface device list by IP address.
265 *
266 * @param ip_addr the network interface device IP address
267 *
268 * @return != NULL: network interface device object
269 * NULL: get failed
270 */
netdev_get_by_ipaddr(ip_addr_t * ip_addr)271 struct netdev *netdev_get_by_ipaddr(ip_addr_t *ip_addr)
272 {
273 rt_slist_t *node = RT_NULL;
274 struct netdev *netdev = RT_NULL;
275
276 if (netdev_list == RT_NULL)
277 {
278 return RT_NULL;
279 }
280
281 rt_spin_lock(&_spinlock);
282
283 for (node = &(netdev_list->list); node; node = rt_slist_next(node))
284 {
285 netdev = rt_slist_entry(node, struct netdev, list);
286 if (netdev && ip_addr_cmp(&(netdev->ip_addr), ip_addr))
287 {
288 rt_spin_unlock(&_spinlock);
289 return netdev;
290 }
291 }
292
293 rt_spin_unlock(&_spinlock);
294
295 return RT_NULL;
296 }
297
298 /**
299 * This function will get network interface device
300 * in network interface device list by netdev name.
301 *
302 * @param name the network interface device name
303 *
304 * @return != NULL: network interface device object
305 * NULL: get failed
306 */
netdev_get_by_name(const char * name)307 struct netdev *netdev_get_by_name(const char *name)
308 {
309 rt_slist_t *node = RT_NULL;
310 struct netdev *netdev = RT_NULL;
311
312 if (netdev_list == RT_NULL)
313 {
314 return RT_NULL;
315 }
316
317 rt_spin_lock(&_spinlock);
318
319 for (node = &(netdev_list->list); node; node = rt_slist_next(node))
320 {
321 netdev = rt_slist_entry(node, struct netdev, list);
322 if (netdev && (rt_strncmp(netdev->name, name, rt_strlen(name) < RT_NAME_MAX ? rt_strlen(name) : RT_NAME_MAX) == 0))
323 {
324 rt_spin_unlock(&_spinlock);
325 return netdev;
326 }
327 }
328
329 rt_spin_unlock(&_spinlock);
330
331 return RT_NULL;
332 }
333
334 /**
335 * This function will get network interface device
336 * in network interface device list by netdev ifindex.
337 *
338 * @param ifindex the ifindex of network interface device
339 *
340 * @return != NULL: network interface device object
341 * NULL: get failed
342 */
netdev_get_by_ifindex(int ifindex)343 struct netdev *netdev_get_by_ifindex(int ifindex)
344 {
345 rt_slist_t *node = RT_NULL;
346 struct netdev *netdev = RT_NULL;
347
348 if (netdev_list == RT_NULL)
349 {
350 return RT_NULL;
351 }
352
353 rt_spin_lock(&_spinlock);
354
355 for (node = &(netdev_list->list); node; node = rt_slist_next(node))
356 {
357 netdev = rt_slist_entry(node, struct netdev, list);
358 if (netdev && (netdev->ifindex == ifindex))
359 {
360 rt_spin_unlock(&_spinlock);
361 return netdev;
362 }
363 }
364
365 rt_spin_unlock(&_spinlock);
366
367 return RT_NULL;
368 }
369
370 #ifdef RT_USING_SAL
371 /**
372 * This function will get the first network interface device
373 * in network interface device list by protocol family type.
374 *
375 * @param family the network interface device protocol family type
376 *
377 * @return != NULL: network interface device object
378 * NULL: get failed
379 */
netdev_get_by_family(int family)380 struct netdev *netdev_get_by_family(int family)
381 {
382 rt_slist_t *node = RT_NULL;
383 struct netdev *netdev = RT_NULL;
384 struct sal_proto_family *pf = RT_NULL;
385
386 if (netdev_list == RT_NULL)
387 {
388 return RT_NULL;
389 }
390
391 rt_spin_lock(&_spinlock);
392
393 for (node = &(netdev_list->list); node; node = rt_slist_next(node))
394 {
395 netdev = rt_slist_entry(node, struct netdev, list);
396 pf = (struct sal_proto_family *) netdev->sal_user_data;
397 if (pf && pf->skt_ops && pf->family == family && netdev_is_up(netdev))
398 {
399 rt_spin_unlock(&_spinlock);
400 return netdev;
401 }
402 }
403
404 for (node = &(netdev_list->list); node; node = rt_slist_next(node))
405 {
406 netdev = rt_slist_entry(node, struct netdev, list);
407 pf = (struct sal_proto_family *) netdev->sal_user_data;
408 if (pf && pf->skt_ops && pf->sec_family == family && netdev_is_up(netdev))
409 {
410 rt_spin_unlock(&_spinlock);
411 return netdev;
412 }
413 }
414
415 rt_spin_unlock(&_spinlock);
416
417 return RT_NULL;
418 }
419
420 /**
421 * This function will get the family type from network interface device
422 *
423 * @param netdev network interface device object
424 *
425 * @return the network interface device family type
426 */
netdev_family_get(struct netdev * netdev)427 int netdev_family_get(struct netdev *netdev)
428 {
429 RT_ASSERT(netdev);
430
431 return ((struct sal_proto_family *)netdev->sal_user_data)->family;
432 }
433
434 #endif /* RT_USING_SAL */
435
436 #if defined(SAL_USING_AF_NETLINK)
netdev_getnetdev(struct msg_buf * msg,int (* cb)(struct msg_buf * m_buf,struct netdev * nd,int nd_num,int index,int ipvx))437 int netdev_getnetdev(struct msg_buf *msg, int (*cb)(struct msg_buf *m_buf, struct netdev *nd, int nd_num, int index, int ipvx))
438 {
439 struct netdev *cur_nd_list = netdev_list;
440 struct netdev *nd_node;
441 int nd_num = 0;
442 int err = 0;
443
444 if (cur_nd_list == RT_NULL)
445 return 0;
446
447 rt_spin_lock(&_spinlock);
448 nd_num = rt_slist_len(&cur_nd_list->list) + 1;
449 rt_spin_unlock(&_spinlock);
450
451 err = cb(msg, cur_nd_list, nd_num, nd.ifindex, ROUTE_IPV4_TRUE);
452 if (err < 0)
453 return err;
454
455
456 rt_spin_lock(&_spinlock);
457 rt_slist_for_each_entry(nd_node, &(cur_nd_list->list), list)
458 {
459 rt_spin_unlock(&_spinlock);
460 err = cb(msg, nd_node, nd_num, nd.ifindex, ROUTE_IPV4_TRUE);
461 if (err < 0)
462 {
463 return err;
464 }
465
466 rt_spin_lock(&_spinlock);
467 }
468 rt_spin_unlock(&_spinlock);
469
470 return 0;
471 }
472 #endif
473
474 /**
475 * This function will set default network interface device.
476 *
477 * @param netdev the network interface device to change
478 */
netdev_set_default(struct netdev * netdev)479 void netdev_set_default(struct netdev *netdev)
480 {
481 if (netdev && (netdev != netdev_default))
482 {
483 netdev_default = netdev;
484
485 /* execture the default network interface device in the current network stack */
486 if (netdev->ops && netdev->ops->set_default)
487 {
488 netdev->ops->set_default(netdev);
489 }
490
491 /* execture application netdev default change callback */
492 if (g_netdev_default_change_callback)
493 {
494 g_netdev_default_change_callback(netdev, NETDEV_CB_DEFAULT_CHANGE);
495 }
496 LOG_D("Setting default network interface device name(%s) successfully.", netdev->name);
497 }
498 }
499
500 /**
501 * This function will set defalut netdev change callback
502 *
503 * @param register_callback the network default change callback
504 *
505 */
netdev_set_default_change_callback(netdev_callback_fn register_callback)506 void netdev_set_default_change_callback(netdev_callback_fn register_callback)
507 {
508 g_netdev_default_change_callback = register_callback;
509 }
510
511 /**
512 * This function will enable network interface device .
513 *
514 * @param netdev the network interface device to change
515 *
516 * @return 0: set status successfully
517 * -1: set status failed
518 */
netdev_set_up(struct netdev * netdev)519 int netdev_set_up(struct netdev *netdev)
520 {
521 int err = 0;
522
523 RT_ASSERT(netdev);
524
525 if (!netdev->ops || !netdev->ops->set_up)
526 {
527 LOG_E("The network interface device(%s) not support to set status.", netdev->name);
528 return -RT_ERROR;
529 }
530
531 /* network interface device status flags check */
532 if (netdev_is_up(netdev))
533 {
534 return RT_EOK;
535 }
536
537 /* execute enable network interface device operations by network interface device driver */
538 err = netdev->ops->set_up(netdev);
539
540 #if defined(SAL_USING_AF_NETLINK)
541 if (err)
542 rtnl_ip_notify(netdev, RTM_NEWLINK);
543 #endif
544
545 return err;
546 }
547 /**
548 * This function will disable network interface device.
549 *
550 * @param netdev the network interface device to change
551 *
552 * @return 0: set status successfully
553 * -1: set sttaus failed
554 */
netdev_set_down(struct netdev * netdev)555 int netdev_set_down(struct netdev *netdev)
556 {
557 int err;
558
559 RT_ASSERT(netdev);
560
561 if (!netdev->ops || !netdev->ops->set_down)
562 {
563 LOG_E("The network interface device(%s) not support to set status.", netdev->name);
564 return -RT_ERROR;
565 }
566
567 /* network interface device status flags check */
568 if (!netdev_is_up(netdev))
569 {
570 return RT_EOK;
571 }
572
573 /* execute disable network interface device operations by network interface driver */
574 err = netdev->ops->set_down(netdev);
575 #if defined(SAL_USING_AF_NETLINK)
576 if (err)
577 rtnl_ip_notify(netdev, RTM_NEWLINK);
578 #endif
579
580 return err;
581 }
582
583 #ifdef RT_LWIP_DHCP
584 /**
585 * This function will control network interface device DHCP capability enable or disable.
586 *
587 * @param netdev the network interface device device to change
588 * @param is_enable the new DHCP status
589 *
590 * @return 0: set DHCP status successfully
591 * -1: set DHCP status failed
592 */
netdev_dhcp_enabled(struct netdev * netdev,rt_bool_t is_enabled)593 int netdev_dhcp_enabled(struct netdev *netdev, rt_bool_t is_enabled)
594 {
595 RT_ASSERT(netdev);
596
597 if (!netdev->ops || !netdev->ops->set_dhcp)
598 {
599 LOG_E("The network interface device(%s) not support to set DHCP status.", netdev->name);
600 return -RT_ERROR;
601 }
602
603 /* network interface device DHCP flags check */
604 if (netdev_is_dhcp_enabled(netdev) == is_enabled)
605 {
606 return RT_EOK;
607 }
608
609 /* execute network interface device DHCP capability control operations */
610 return netdev->ops->set_dhcp(netdev, is_enabled);
611 }
612
netdev_dhcp_open(char * netdev_name)613 int netdev_dhcp_open(char *netdev_name)
614 {
615 struct netdev *netdev = RT_NULL;
616 netdev = netdev_get_by_name(netdev_name);
617 if (netdev == RT_NULL)
618 {
619 rt_kprintf("bad network interface device name(%s).\n", netdev_name);
620 return -1;
621 }
622 netdev_dhcp_enabled(netdev, RT_TRUE);
623 return 0;
624 }
625
netdev_dhcp_close(char * netdev_name)626 int netdev_dhcp_close(char *netdev_name)
627 {
628 struct netdev *netdev = RT_NULL;
629
630 netdev = netdev_get_by_name(netdev_name);
631 if (netdev == RT_NULL)
632 {
633 rt_kprintf("bad network interface device name(%s).\n", netdev_name);
634 return -1;
635 }
636 netdev_dhcp_enabled(netdev, RT_FALSE);
637 return 0;
638 }
639 #endif /* RT_LWIP_DHCP */
640
641 /**
642 * This function will set network interface device IP address.
643 *
644 * @param netdev the network interface device to change
645 * @param ip_addr the new IP address
646 *
647 * @return 0: set IP address successfully
648 * -1: set IP address failed
649 */
netdev_set_ipaddr(struct netdev * netdev,const ip_addr_t * ip_addr)650 int netdev_set_ipaddr(struct netdev *netdev, const ip_addr_t *ip_addr)
651 {
652 int err;
653 RT_ASSERT(netdev);
654 RT_ASSERT(ip_addr);
655
656 if (!netdev->ops || !netdev->ops->set_addr_info)
657 {
658 LOG_E("The network interface device(%s) not support to set IP address.", netdev->name);
659 return -RT_ERROR;
660 }
661
662 if (netdev_is_dhcp_enabled(netdev))
663 {
664 LOG_E("The network interface device(%s) DHCP capability is enable, not support set IP address.", netdev->name);
665 return -RT_ERROR;
666 }
667
668 /* execute network interface device set IP address operations */
669 err = netdev->ops->set_addr_info(netdev, (ip_addr_t *)ip_addr, RT_NULL, RT_NULL);
670
671 #if defined(SAL_USING_AF_NETLINK)
672 if (err == 0)
673 rtnl_ip_notify(netdev, RTM_SETLINK);
674 #endif
675
676
677 return err;
678 }
679
680 /**
681 * This function will set network interface device netmask address.
682 *
683 * @param netdev the network interface device to change
684 * @param netmask the new netmask address
685 *
686 * @return 0: set netmask address successfully
687 * -1: set netmask address failed
688 */
netdev_set_netmask(struct netdev * netdev,const ip_addr_t * netmask)689 int netdev_set_netmask(struct netdev *netdev, const ip_addr_t *netmask)
690 {
691 RT_ASSERT(netdev);
692 RT_ASSERT(netmask);
693
694 if (!netdev->ops || !netdev->ops->set_addr_info)
695 {
696 LOG_E("The network interface device(%s) not support to set netmask address.", netdev->name);
697 return -RT_ERROR;
698 }
699
700 if (netdev_is_dhcp_enabled(netdev))
701 {
702 LOG_E("The network interface device(%s) DHCP capability is enable, not support set netmask address.", netdev->name);
703 return -RT_ERROR;
704 }
705
706 /* execute network interface device set netmask address operations */
707 return netdev->ops->set_addr_info(netdev, RT_NULL, (ip_addr_t *)netmask, RT_NULL);
708 }
709
710 /**
711 * This function will set network interface device gateway address.
712 *
713 * @param netdev the network interface device to change
714 * @param gw the new gateway address
715 *
716 * @return 0: set gateway address successfully
717 * -1: set gateway address failed
718 */
netdev_set_gw(struct netdev * netdev,const ip_addr_t * gw)719 int netdev_set_gw(struct netdev *netdev, const ip_addr_t *gw)
720 {
721 RT_ASSERT(netdev);
722 RT_ASSERT(gw);
723
724 if (!netdev->ops || !netdev->ops->set_addr_info)
725 {
726 LOG_E("The network interface device(%s) not support to set gateway address.", netdev->name);
727 return -RT_ERROR;
728 }
729
730 if (netdev_is_dhcp_enabled(netdev))
731 {
732 LOG_E("The network interface device(%s) DHCP capability is enable, not support set gateway address.", netdev->name);
733 return -RT_ERROR;
734 }
735
736 /* execute network interface device set gateway address operations */
737 return netdev->ops->set_addr_info(netdev, RT_NULL, RT_NULL, (ip_addr_t *)gw);
738 }
739
740 /**
741 * This function will try to get network device and set DNS server address.
742 *
743 * @param netdev_name the network interface device name
744 * @param dns_num the number of the DNS server
745 * @param dns_server the new DNS server address
746 */
netdev_set_dns(char * netdev_name,uint8_t dns_num,char * dns_server)747 void netdev_set_dns(char *netdev_name, uint8_t dns_num, char *dns_server)
748 {
749 struct netdev *netdev = RT_NULL;
750 ip_addr_t dns_addr;
751
752 netdev = netdev_get_by_name(netdev_name);
753 if (netdev == RT_NULL)
754 {
755 rt_kprintf("bad network interface device name(%s).\n", netdev_name);
756 return;
757 }
758
759 inet_aton(dns_server, &dns_addr);
760 if (netdev_set_dns_server(netdev, dns_num, &dns_addr) == RT_EOK)
761 {
762 rt_kprintf("set network interface device(%s) dns server #%d: %s\n", netdev_name, dns_num, dns_server);
763 }
764 }
765
766 /**
767 * This function will set network interface device DNS server address.
768 *
769 * @param netdev the network interface device to change
770 * @param dns_num the number of the DNS server
771 * @param dns_server the new DNS server address
772 *
773 * @return 0: set netmask address successfully
774 * -1: set netmask address failed
775 */
netdev_set_dns_server(struct netdev * netdev,uint8_t dns_num,const ip_addr_t * dns_server)776 int netdev_set_dns_server(struct netdev *netdev, uint8_t dns_num, const ip_addr_t *dns_server)
777 {
778 RT_ASSERT(netdev);
779 RT_ASSERT(dns_server);
780
781 if (dns_num >= NETDEV_DNS_SERVERS_NUM)
782 {
783 LOG_E("The number of DNS servers(%d) set exceeds the maximum number(%d).", dns_num + 1, NETDEV_DNS_SERVERS_NUM);
784 return -RT_ERROR;
785 }
786
787 if (!netdev->ops || !netdev->ops->set_dns_server)
788 {
789 LOG_E("The network interface device(%s) not support to set DNS server address.", netdev->name);
790 return -RT_ERROR;
791 }
792
793 /* execute network interface device set DNS server address operations */
794 return netdev->ops->set_dns_server(netdev, dns_num, (ip_addr_t *)dns_server);
795 }
796
797 /**
798 * This function will set network interface device IP, gateway and netmask address according to device name.
799 *
800 * @param netdev_name the network interface device name
801 * @param ip_addr the new IP address
802 * @param gw_addr the new gateway address
803 * @param nm_addr the new netmask address
804 */
netdev_set_if(char * netdev_name,char * ip_addr,char * gw_addr,char * nm_addr)805 void netdev_set_if(char *netdev_name, char *ip_addr, char *gw_addr, char *nm_addr)
806 {
807 struct netdev *netdev = RT_NULL;
808 ip_addr_t addr;
809
810 netdev = netdev_get_by_name(netdev_name);
811 if (netdev == RT_NULL)
812 {
813 rt_kprintf("bad network interface device name(%s).\n", netdev_name);
814 return;
815 }
816
817 #ifdef RT_LWIP_DHCP
818 netdev_dhcp_close(netdev_name);
819 #endif
820
821 /* set IP address */
822 if ((ip_addr != RT_NULL) && inet_aton(ip_addr, &addr))
823 {
824 netdev_set_ipaddr(netdev, &addr);
825 }
826
827 /* set gateway address */
828 if ((gw_addr != RT_NULL) && inet_aton(gw_addr, &addr))
829 {
830 netdev_set_gw(netdev, &addr);
831 }
832
833 /* set netmask address */
834 if ((nm_addr != RT_NULL) && inet_aton(nm_addr, &addr))
835 {
836 netdev_set_netmask(netdev, &addr);
837 }
838 }
839
840 /**
841 * This function will set callback to be called when the network interface device status has been changed.
842 *
843 * @param netdev the network interface device to change
844 * @param status_callback the callback be called when the status has been changed.
845 */
netdev_set_status_callback(struct netdev * netdev,netdev_callback_fn status_callback)846 void netdev_set_status_callback(struct netdev *netdev, netdev_callback_fn status_callback)
847 {
848 RT_ASSERT(netdev);
849 RT_ASSERT(status_callback);
850
851 netdev->status_callback = status_callback;
852 }
853
854 /**
855 * This function will set callback to be called when the network interface device address has been changed.
856 *
857 * @param netdev the network interface device to change
858 * @param addr_callback the callback be called when the address has been changed.
859 */
netdev_set_addr_callback(struct netdev * netdev,netdev_callback_fn addr_callback)860 void netdev_set_addr_callback(struct netdev *netdev, netdev_callback_fn addr_callback)
861 {
862 RT_ASSERT(netdev);
863 RT_ASSERT(addr_callback);
864
865 netdev->addr_callback = addr_callback;
866 }
867
868
869 /**
870 * This function will set network interface device IP address.
871 * @NOTE it can only be called in the network interface device driver.
872 *
873 * @param netdev the network interface device to change
874 * @param ip_addr the new IP address
875 */
netdev_low_level_set_ipaddr(struct netdev * netdev,const ip_addr_t * ip_addr)876 void netdev_low_level_set_ipaddr(struct netdev *netdev, const ip_addr_t *ip_addr)
877 {
878 RT_ASSERT(ip_addr);
879
880 if (netdev && ip_addr_cmp(&(netdev->ip_addr), ip_addr) == 0)
881 {
882 ip_addr_copy(netdev->ip_addr, *ip_addr);
883
884 #ifdef RT_USING_SAL
885 /* set network interface device flags to internet up */
886 if (netdev_is_up(netdev) && netdev_is_link_up(netdev))
887 {
888 sal_check_netdev_internet_up(netdev);
889 }
890 #endif /* RT_USING_SAL */
891
892 /* execute IP address change callback function */
893 if (netdev->addr_callback)
894 {
895 netdev->addr_callback(netdev, NETDEV_CB_ADDR_IP);
896 }
897 }
898 }
899
900 /**
901 * This function will set network interface device netmask address.
902 * @NOTE it can only be called in the network interface device driver.
903 *
904 * @param netdev the network interface device to change
905 * @param netmask the new netmask address
906 */
netdev_low_level_set_netmask(struct netdev * netdev,const ip_addr_t * netmask)907 void netdev_low_level_set_netmask(struct netdev *netdev, const ip_addr_t *netmask)
908 {
909 RT_ASSERT(netmask);
910
911 if (netdev && ip_addr_cmp(&(netdev->netmask), netmask) == 0)
912 {
913 ip_addr_copy(netdev->netmask, *netmask);
914
915 #ifdef RT_USING_SAL
916 /* set network interface device flags to internet up */
917 if (netdev_is_up(netdev) && netdev_is_link_up(netdev) &&
918 !ip_addr_isany(&(netdev->ip_addr)))
919 {
920 sal_check_netdev_internet_up(netdev);
921 }
922 #endif /* RT_USING_SAL */
923
924 /* execute netmask address change callback function */
925 if (netdev->addr_callback)
926 {
927 netdev->addr_callback(netdev, NETDEV_CB_ADDR_NETMASK);
928 }
929 }
930 }
931
932 /**
933 * This function will set network interface device gateway address.
934 * @NOTE it can only be called in the network interface device driver.
935 *
936 * @param netdev the network interface device to change
937 * @param gw the new gateway address
938 */
netdev_low_level_set_gw(struct netdev * netdev,const ip_addr_t * gw)939 void netdev_low_level_set_gw(struct netdev *netdev, const ip_addr_t *gw)
940 {
941 RT_ASSERT(gw);
942
943 if (netdev && ip_addr_cmp(&(netdev->gw), gw) == 0)
944 {
945 ip_addr_copy(netdev->gw, *gw);
946
947 #ifdef RT_USING_SAL
948 /* set network interface device flags to internet up */
949 if (netdev_is_up(netdev) && netdev_is_link_up(netdev) &&
950 !ip_addr_isany(&(netdev->ip_addr)))
951 {
952 sal_check_netdev_internet_up(netdev);
953 }
954 #endif /* RT_USING_SAL */
955
956 /* execute gateway address change callback function */
957 if (netdev->addr_callback)
958 {
959 netdev->addr_callback(netdev, NETDEV_CB_ADDR_GATEWAY);
960 }
961 }
962 }
963
964 /**
965 * This function will set network interface device DNS server address.
966 * @NOTE it can only be called in the network interface device driver.
967 *
968 * @param netdev the network interface device to change
969 * @param dns_num the number of the DNS server
970 * @param dns_server the new DNS server address
971 *
972 */
netdev_low_level_set_dns_server(struct netdev * netdev,uint8_t dns_num,const ip_addr_t * dns_server)973 void netdev_low_level_set_dns_server(struct netdev *netdev, uint8_t dns_num, const ip_addr_t *dns_server)
974 {
975 unsigned int index;
976
977 RT_ASSERT(dns_server);
978
979 if (netdev == RT_NULL)
980 {
981 return;
982 }
983 /* check DNS servers is exist */
984 for (index = 0; index < NETDEV_DNS_SERVERS_NUM; index++)
985 {
986 if (ip_addr_cmp(&(netdev->dns_servers[index]), dns_server))
987 {
988 return;
989 }
990 }
991
992 if (dns_num < NETDEV_DNS_SERVERS_NUM)
993 {
994 ip_addr_copy(netdev->dns_servers[dns_num], *dns_server);
995
996 /* execute DNS servers address change callback function */
997 if (netdev->addr_callback)
998 {
999 netdev->addr_callback(netdev, NETDEV_CB_ADDR_DNS_SERVER);
1000 }
1001 }
1002 }
1003
1004 #ifdef NETDEV_USING_AUTO_DEFAULT
1005 /* Change to the first link_up network interface device automatically */
netdev_auto_change_default(struct netdev * netdev)1006 static void netdev_auto_change_default(struct netdev *netdev)
1007 {
1008 struct netdev *new_netdev = RT_NULL;
1009
1010 if (netdev->flags & NETDEV_FLAG_LINK_UP)
1011 {
1012 if (!(netdev_default->flags & NETDEV_FLAG_LINK_UP))
1013 {
1014 netdev_set_default(netdev);
1015 }
1016 return;
1017 }
1018 if (rt_memcmp(netdev, netdev_default, sizeof(struct netdev)) == 0)
1019 {
1020 new_netdev = netdev_get_first_by_flags(NETDEV_FLAG_LINK_UP);
1021 if (new_netdev)
1022 {
1023 netdev_set_default(new_netdev);
1024 }
1025 }
1026 }
1027 #endif /* NETDEV_USING_AUTO_DEFAULT */
1028
1029 /**
1030 * This function will set network interface device status.
1031 * @NOTE it can only be called in the network interface device driver.
1032 *
1033 * @param netdev the network interface device to change
1034 * @param is_up the new status
1035 */
netdev_low_level_set_status(struct netdev * netdev,rt_bool_t is_up)1036 void netdev_low_level_set_status(struct netdev *netdev, rt_bool_t is_up)
1037 {
1038 if (netdev && netdev_is_up(netdev) != is_up)
1039 {
1040 if (is_up)
1041 {
1042 netdev->flags |= NETDEV_FLAG_UP;
1043 }
1044 else
1045 {
1046 netdev->flags &= ~NETDEV_FLAG_UP;
1047
1048 #ifdef NETDEV_USING_AUTO_DEFAULT
1049 /* change to the first link_up network interface device automatically */
1050 netdev_auto_change_default(netdev);
1051 #endif /* NETDEV_USING_AUTO_DEFAULT */
1052 }
1053
1054 /* execute network interface device status change callback function */
1055 if (netdev->status_callback)
1056 {
1057 netdev->status_callback(netdev, is_up ? NETDEV_CB_STATUS_UP : NETDEV_CB_STATUS_DOWN);
1058 }
1059 }
1060 }
1061
1062 /**
1063 * This function will set network interface device active link status.
1064 * @NOTE it can only be called in the network interface device driver.
1065 *
1066 * @param netdev the network interface device to change
1067 * @param is_up the new link status
1068 */
netdev_low_level_set_link_status(struct netdev * netdev,rt_bool_t is_up)1069 void netdev_low_level_set_link_status(struct netdev *netdev, rt_bool_t is_up)
1070 {
1071 if (netdev && netdev_is_link_up(netdev) != is_up)
1072 {
1073 if (is_up)
1074 {
1075 netdev->flags |= NETDEV_FLAG_LINK_UP;
1076
1077 #ifdef RT_USING_SAL
1078 /* set network interface device flags to internet up */
1079 if (netdev_is_up(netdev) && !ip_addr_isany(&(netdev->ip_addr)))
1080 {
1081 sal_check_netdev_internet_up(netdev);
1082 }
1083 #endif /* RT_USING_SAL */
1084 }
1085 else
1086 {
1087 netdev->flags &= ~NETDEV_FLAG_LINK_UP;
1088
1089 /* set network interface device flags to internet down */
1090 netdev->flags &= ~NETDEV_FLAG_INTERNET_UP;
1091
1092 #ifdef NETDEV_USING_AUTO_DEFAULT
1093 /* change to the first link_up network interface device automatically */
1094 netdev_auto_change_default(netdev);
1095 #endif /* NETDEV_USING_AUTO_DEFAULT */
1096 }
1097
1098 /* execute link status change callback function */
1099 if (netdev->status_callback)
1100 {
1101 netdev->status_callback(netdev, is_up ? NETDEV_CB_STATUS_LINK_UP : NETDEV_CB_STATUS_LINK_DOWN);
1102 }
1103 }
1104 }
1105
1106 /**
1107 * This function will set network interface device active internet status.
1108 * @NOTE it can only be called in the network interface device driver.
1109 *
1110 * @param netdev the network interface device to change
1111 * @param is_up the new internet status
1112 */
netdev_low_level_set_internet_status(struct netdev * netdev,rt_bool_t is_up)1113 void netdev_low_level_set_internet_status(struct netdev *netdev, rt_bool_t is_up)
1114 {
1115 if (netdev && netdev_is_internet_up(netdev) != is_up)
1116 {
1117 if (is_up)
1118 {
1119 netdev->flags |= NETDEV_FLAG_INTERNET_UP;
1120 }
1121 else
1122 {
1123 netdev->flags &= ~NETDEV_FLAG_INTERNET_UP;
1124 }
1125
1126 /* execute network interface device status change callback function */
1127 if (netdev->status_callback)
1128 {
1129 netdev->status_callback(netdev, is_up ? NETDEV_CB_STATUS_INTERNET_UP : NETDEV_CB_STATUS_INTERNET_DOWN);
1130 }
1131 }
1132 }
1133
1134 /**
1135 * This function will set network interface device DHCP status.
1136 * @NOTE it can only be called in the network interface device driver.
1137 *
1138 * @param netdev the network interface device to change
1139 * @param is_up the new DHCP status
1140 */
netdev_low_level_set_dhcp_status(struct netdev * netdev,rt_bool_t is_enable)1141 void netdev_low_level_set_dhcp_status(struct netdev *netdev, rt_bool_t is_enable)
1142 {
1143 if (netdev && netdev_is_dhcp_enabled(netdev) != is_enable)
1144 {
1145 if (is_enable)
1146 {
1147 netdev->flags |= NETDEV_FLAG_DHCP;
1148 }
1149 else
1150 {
1151 netdev->flags &= ~NETDEV_FLAG_DHCP;
1152 }
1153
1154 /* execute DHCP status change callback function */
1155 if (netdev->status_callback)
1156 {
1157 netdev->status_callback(netdev, is_enable ? NETDEV_CB_STATUS_DHCP_ENABLE : NETDEV_CB_STATUS_DHCP_DISABLE);
1158 }
1159 }
1160 }
1161
1162 #ifdef RT_USING_FINSH
1163
1164 #include <finsh.h>
1165
1166 #ifdef NETDEV_USING_IFCONFIG
netdev_list_if(void)1167 static void netdev_list_if(void)
1168 {
1169 #define NETDEV_IFCONFIG_MAC_MAX_LEN 6
1170 #define NETDEV_IFCONFIG_IMEI_MAX_LEN 8
1171
1172 rt_ubase_t index;
1173 rt_slist_t *node = RT_NULL;
1174 struct netdev *netdev = RT_NULL;
1175 struct netdev *cur_netdev_list = netdev_list;
1176
1177 if (cur_netdev_list == RT_NULL)
1178 {
1179 rt_kprintf("ifconfig: network interface device list error.\n");
1180 return;
1181 }
1182
1183 for (node = &(cur_netdev_list->list); node; node = rt_slist_next(node))
1184 {
1185 netdev = rt_list_entry(node, struct netdev, list);
1186
1187 rt_kprintf("network interface device: %.*s%s\n",
1188 RT_NAME_MAX, netdev->name,
1189 (netdev == netdev_default) ? " (Default)" : "");
1190 rt_kprintf("MTU: %d\n", netdev->mtu);
1191
1192 /* 6 - MAC address, 8 - IEMI */
1193 if (netdev->hwaddr_len == NETDEV_IFCONFIG_MAC_MAX_LEN)
1194 {
1195 rt_kprintf("MAC: ");
1196 for (index = 0; index < netdev->hwaddr_len; index++)
1197 {
1198 rt_kprintf("%02x ", netdev->hwaddr[index]);
1199 }
1200 }
1201 else if (netdev->hwaddr_len == NETDEV_IFCONFIG_IMEI_MAX_LEN)
1202 {
1203 rt_kprintf("IMEI: ");
1204 for (index = 0; index < netdev->hwaddr_len; index++)
1205 {
1206 /* two numbers are displayed at one time*/
1207 if (netdev->hwaddr[index] < 10 && index != netdev->hwaddr_len - 1)
1208 {
1209 rt_kprintf("%02d", netdev->hwaddr[index]);
1210 }
1211 else
1212 {
1213 rt_kprintf("%d", netdev->hwaddr[index]);
1214 }
1215
1216
1217 }
1218 }
1219
1220 rt_kprintf("\nFLAGS:");
1221 if (netdev->flags & NETDEV_FLAG_UP) rt_kprintf(" UP");
1222 else rt_kprintf(" DOWN");
1223 if (netdev->flags & NETDEV_FLAG_LINK_UP) rt_kprintf(" LINK_UP");
1224 else rt_kprintf(" LINK_DOWN");
1225 #ifdef SAL_INTERNET_CHECK
1226 if (netdev->flags & NETDEV_FLAG_INTERNET_UP) rt_kprintf(" INTERNET_UP");
1227 else rt_kprintf(" INTERNET_DOWN");
1228 #endif
1229 if (netdev->flags & NETDEV_FLAG_DHCP) rt_kprintf(" DHCP_ENABLE");
1230 else rt_kprintf(" DHCP_DISABLE");
1231 if (netdev->flags & NETDEV_FLAG_ETHARP) rt_kprintf(" ETHARP");
1232 if (netdev->flags & NETDEV_FLAG_BROADCAST) rt_kprintf(" BROADCAST");
1233 if (netdev->flags & NETDEV_FLAG_IGMP) rt_kprintf(" IGMP");
1234 rt_kprintf("\n");
1235 rt_kprintf("ip address: %s\n", inet_ntoa(netdev->ip_addr));
1236 rt_kprintf("gw address: %s\n", inet_ntoa(netdev->gw));
1237 rt_kprintf("net mask : %s\n", inet_ntoa(netdev->netmask));
1238
1239 #if NETDEV_IPV6
1240 {
1241 ip_addr_t *addr;
1242 int i;
1243
1244 addr = &netdev->ip6_addr[0];
1245
1246 if (!ip_addr_isany(addr))
1247 {
1248 rt_kprintf("ipv6 link-local: %s %s\n", inet_ntoa(*addr),
1249 !ip_addr_isany(addr) ? "VALID" : "INVALID");
1250
1251 for (i = 1; i < NETDEV_IPV6_NUM_ADDRESSES; i++)
1252 {
1253 addr = &netdev->ip6_addr[i];
1254 rt_kprintf("ipv6[%d] address: %s %s\n", i, inet_ntoa(*addr),
1255 !ip_addr_isany(addr) ? "VALID" : "INVALID");
1256 }
1257 }
1258 }
1259 #endif /* NETDEV_IPV6 */
1260
1261 for (index = 0; index < NETDEV_DNS_SERVERS_NUM; index++)
1262 {
1263 rt_kprintf("dns server #%d: %s\n", index, inet_ntoa(netdev->dns_servers[index]));
1264 }
1265
1266 if (rt_slist_next(node))
1267 {
1268 rt_kprintf("\n");
1269 }
1270 }
1271 }
1272
netdev_ifconfig(int argc,char ** argv)1273 int netdev_ifconfig(int argc, char **argv)
1274 {
1275 if (argc == 1)
1276 {
1277 netdev_list_if();
1278 }
1279 #ifdef RT_LWIP_DHCP
1280 else if(argc == 3)
1281 {
1282 if (!strcmp(argv[2], "dhcp"))
1283 {
1284 netdev_dhcp_open(argv[1]);
1285 }
1286 }
1287 #endif
1288 else if (argc == 5)
1289 {
1290 rt_kprintf("config : %s\n", argv[1]);
1291 rt_kprintf("IP addr: %s\n", argv[2]);
1292 rt_kprintf("Gateway: %s\n", argv[3]);
1293 rt_kprintf("netmask: %s\n", argv[4]);
1294 netdev_set_if(argv[1], argv[2], argv[3], argv[4]);
1295 }
1296 else
1297 {
1298 rt_kprintf("bad parameter! e.g: ifconfig e0 192.168.1.30 192.168.1.1 255.255.255.0\n");
1299 #ifdef RT_LWIP_DHCP
1300 rt_kprintf("bad parameter! e.g: ifconfig e0 dhcp\n");
1301 #endif
1302 }
1303
1304 return 0;
1305 }
1306 MSH_CMD_EXPORT_ALIAS(netdev_ifconfig, ifconfig, list the information of all network interfaces);
1307 #endif /* NETDEV_USING_IFCONFIG */
1308
1309 #ifdef NETDEV_USING_PING
netdev_cmd_ping(char * target_name,char * netdev_name,rt_uint32_t times,rt_size_t size)1310 int netdev_cmd_ping(char* target_name, char *netdev_name, rt_uint32_t times, rt_size_t size)
1311 {
1312 #define NETDEV_PING_DATA_SIZE 32
1313 /** ping receive timeout - in milliseconds */
1314 #define NETDEV_PING_RECV_TIMEO (2 * RT_TICK_PER_SECOND)
1315 /** ping delay - in milliseconds */
1316 #define NETDEV_PING_DELAY (1 * RT_TICK_PER_SECOND)
1317 /* check netdev ping options */
1318 #define NETDEV_PING_IS_COMMONICABLE(netdev) \
1319 ((netdev) && (netdev)->ops && (netdev)->ops->ping && \
1320 netdev_is_up(netdev) && netdev_is_link_up(netdev)) \
1321
1322 struct netdev *netdev = RT_NULL;
1323 struct netdev_ping_resp ping_resp;
1324 rt_uint32_t index, received, loss, max_time, min_time, avg_time;
1325 int ret = 0;
1326 rt_bool_t isbind = RT_FALSE;
1327
1328 if (size == 0)
1329 {
1330 size = NETDEV_PING_DATA_SIZE;
1331 }
1332
1333 if (netdev_name != RT_NULL)
1334 {
1335 netdev = netdev_get_by_name(netdev_name);
1336 isbind = RT_TRUE;
1337 }
1338
1339 if (netdev == RT_NULL)
1340 {
1341 netdev = netdev_default;
1342 rt_kprintf("ping: not found specified netif, using default netdev %s.\n", netdev->name);
1343 }
1344
1345 if (!NETDEV_PING_IS_COMMONICABLE(netdev))
1346 {
1347 if (netdev == RT_NULL)
1348 {
1349 rt_kprintf("ping: not found available network interface device.\n");
1350 return -RT_ERROR;
1351 }
1352 else if (netdev->ops == RT_NULL || netdev->ops->ping == RT_NULL)
1353 {
1354 rt_kprintf("ping: network interface device(%s) not support ping feature.\n", netdev->name);
1355 return -RT_ERROR;
1356 }
1357 else if (!netdev_is_up(netdev) || !netdev_is_link_up(netdev))
1358 {
1359 rt_kprintf("ping: network interface device(%s) status error.\n", netdev->name);
1360 return -RT_ERROR;
1361 }
1362 }
1363
1364 max_time = avg_time = received = 0;
1365 min_time = 0xFFFFFFFF;
1366 for (index = 0; index < times; index++)
1367 {
1368 int delay_tick = 0;
1369 rt_tick_t start_tick = 0;
1370
1371 rt_memset(&ping_resp, 0x00, sizeof(struct netdev_ping_resp));
1372 start_tick = rt_tick_get();
1373 ret = netdev->ops->ping(netdev, (const char *)target_name, size, NETDEV_PING_RECV_TIMEO, &ping_resp, isbind);
1374 if (ret == -RT_ETIMEOUT)
1375 {
1376 rt_kprintf("ping: from %s icmp_seq=%d timeout\n",
1377 (ip_addr_isany(&(ping_resp.ip_addr))) ? target_name : inet_ntoa(ping_resp.ip_addr), index + 1);
1378 }
1379 else if (ret == -RT_ERROR)
1380 {
1381 rt_kprintf("ping: unknown %s %s\n",
1382 (ip_addr_isany(&(ping_resp.ip_addr))) ? "host" : "address",
1383 (ip_addr_isany(&(ping_resp.ip_addr))) ? target_name : inet_ntoa(ping_resp.ip_addr));
1384 }
1385 else
1386 {
1387 if (ping_resp.ttl == 0)
1388 {
1389 rt_kprintf("%d bytes from %s icmp_seq=%d time=%d ms\n",
1390 ping_resp.data_len, inet_ntoa(ping_resp.ip_addr), index + 1, ping_resp.ticks);
1391 }
1392 else
1393 {
1394 rt_kprintf("%d bytes from %s icmp_seq=%d ttl=%d time=%d ms\n",
1395 ping_resp.data_len, inet_ntoa(ping_resp.ip_addr), index + 1, ping_resp.ttl, ping_resp.ticks);
1396 }
1397 received += 1;
1398 if (ping_resp.ticks > max_time)
1399 {
1400 max_time = ping_resp.ticks;
1401 }
1402 else if (ping_resp.ticks < min_time)
1403 {
1404 min_time = ping_resp.ticks;
1405 }
1406 avg_time += ping_resp.ticks;
1407 }
1408
1409 /* if the response time is more than NETDEV_PING_DELAY, no need to delay */
1410 delay_tick = ((rt_tick_get() - start_tick) > NETDEV_PING_DELAY) || (index == times) ? 0 : NETDEV_PING_DELAY;
1411 rt_thread_delay(delay_tick);
1412 }
1413
1414 /* print ping statistics */
1415 loss = (uint32_t)((1 - ((float)received) / index) * 100);
1416 avg_time = (uint32_t)(avg_time / received);
1417 #if NETDEV_IPV4 && NETDEV_IPV6
1418 if (IP_IS_V4_VAL(&ping_resp.ip_addr))
1419 {
1420 rt_kprintf("\n--- %s ping statistics ---\n", inet_ntoa(*ip_2_ip4(&ping_resp.ip_addr)));
1421 }
1422 else
1423 {
1424 rt_kprintf("\n--- %s ping statistics ---\n", inet6_ntoa(*ip_2_ip6(&ping_resp.ip_addr)));
1425 }
1426 #elif NETDEV_IPV4
1427 rt_kprintf("\n--- %s ping statistics ---\n", inet_ntoa(ping_resp.ip_addr));
1428 #elif NETDEV_IPV6
1429 rt_kprintf("\n--- %s ping statistics ---\n", inet6_ntoa(ping_resp.ip_addr));
1430 #endif
1431 rt_kprintf("%d packets transmitted, %d received, %d%% packet loss\n", index, received, loss);
1432 if (received > 0)
1433 {
1434 rt_kprintf("minimum = %dms, maximum = %dms, average = %dms\n", min_time, max_time, avg_time);
1435 }
1436
1437 return RT_EOK;
1438 }
1439
netdev_ping(int argc,char ** argv)1440 int netdev_ping(int argc, char **argv)
1441 {
1442 if (argc == 1)
1443 {
1444 rt_kprintf("Please input: ping <host address> [netdev name] [times] [data size]\n");
1445 }
1446 else if (argc == 2)
1447 {
1448 netdev_cmd_ping(argv[1], RT_NULL, 4, 0);
1449 }
1450 else if (argc == 3)
1451 {
1452 netdev_cmd_ping(argv[1], argv[2], 4, 0);
1453 }
1454 else if (argc == 4)
1455 {
1456 netdev_cmd_ping(argv[1], argv[2], atoi(argv[3]), 0);
1457 }
1458 else if (argc == 5)
1459 {
1460 netdev_cmd_ping(argv[1], argv[2], atoi(argv[3]), atoi(argv[4]));
1461 }
1462
1463 return 0;
1464 }
1465 MSH_CMD_EXPORT_ALIAS(netdev_ping, ping, ping network host);
1466 #endif /* NETDEV_USING_PING */
1467
netdev_list_dns(void)1468 static void netdev_list_dns(void)
1469 {
1470 unsigned int index = 0;
1471 struct netdev *netdev = RT_NULL;
1472 rt_slist_t *node = RT_NULL;
1473
1474 for (node = &(netdev_list->list); node; node = rt_slist_next(node))
1475 {
1476 netdev = rt_list_entry(node, struct netdev, list);
1477
1478 rt_kprintf("network interface device: %.*s%s\n",
1479 RT_NAME_MAX, netdev->name,
1480 (netdev == netdev_default)?" (Default)":"");
1481
1482 for(index = 0; index < NETDEV_DNS_SERVERS_NUM; index++)
1483 {
1484 rt_kprintf("dns server #%d: %s\n", index, inet_ntoa(netdev->dns_servers[index]));
1485 }
1486
1487 if (rt_slist_next(node))
1488 {
1489 rt_kprintf("\n");
1490 }
1491 }
1492 }
1493
netdev_dns(int argc,char ** argv)1494 int netdev_dns(int argc, char **argv)
1495 {
1496 if (argc == 1)
1497 {
1498 netdev_list_dns();
1499 }
1500 else if (argc == 3)
1501 {
1502 netdev_set_dns(argv[1], 0, argv[2]);
1503 }
1504 else if (argc == 4)
1505 {
1506 netdev_set_dns(argv[1], atoi(argv[2]), argv[3]);
1507 }
1508 else
1509 {
1510 rt_kprintf("bad parameter! input: dns <netdev_name> [dns_num] <dns_server>\n");
1511 return -1;
1512 }
1513
1514 return 0;
1515 }
1516 MSH_CMD_EXPORT_ALIAS(netdev_dns, dns, list and set the information of dns);
1517
1518 #ifdef NETDEV_USING_NETSTAT
netdev_cmd_netstat(void)1519 static void netdev_cmd_netstat(void)
1520 {
1521 rt_slist_t *node = RT_NULL;
1522 struct netdev *netdev = RT_NULL;
1523 struct netdev *cur_netdev_list = netdev_list;
1524
1525 if (cur_netdev_list == RT_NULL)
1526 {
1527 rt_kprintf("netstat: network interface device list error.\n");
1528 return;
1529 }
1530
1531 for (node = &(cur_netdev_list->list); node; node = rt_slist_next(node))
1532 {
1533 netdev = rt_list_entry(node, struct netdev, list);
1534
1535 if (netdev && netdev->ops && netdev->ops->netstat)
1536 {
1537 break;
1538 }
1539 }
1540
1541 if (netdev->ops->netstat != RT_NULL)
1542 {
1543 netdev->ops->netstat(netdev);
1544 }
1545 else
1546 {
1547 rt_kprintf("netstat: this command is not supported!\n");
1548 }
1549 }
1550
netdev_netstat(int argc,char ** argv)1551 int netdev_netstat(int argc, char **argv)
1552 {
1553 if (argc != 1)
1554 {
1555 rt_kprintf("Please input: netstat \n");
1556 }
1557 else
1558 {
1559 netdev_cmd_netstat();
1560 }
1561
1562 return 0;
1563 }
1564 MSH_CMD_EXPORT_ALIAS(netdev_netstat, netstat, list the information of TCP / IP);
1565 #endif /* NETDEV_USING_NETSTAT */
1566
1567 #endif /* RT_USING_FINSH */
1568