1 /*
2  * Copyright (C) 2015-2020 Alibaba Group Holding Limited
3  */
4 
5 #include <unistd.h>
6 #include <stdio.h>
7 #include <stdlib.h>
8 #include <string.h>
9 #include <fcntl.h>
10 #include <math.h>
11 #include <stdarg.h>
12 
13 #include "k_api.h"
14 #include "ulog/ulog.h"
15 
16 #define TAG "netdev_cli"
17 
18 #include <netdev_ipaddr.h>
19 #include <netdev.h>
20 #include <aos/cli.h>
21 #include <aos/list.h>
22 
23 #define NDEV_PRINT aos_cli_printf
24 
25 #define NDEV_PRINT_BUFFER_SIZE     128
26 
27 typedef struct netdev_fd_info {
28     slist_t next;
29     struct netdev* netdev;
30     int fd;
31 } netdev_fd_info_t;
32 
33 static slist_t g_netdev_fd_list_head;
34 
35 static char netdev_res_print_buffer[NDEV_PRINT_BUFFER_SIZE];
36 
netdev_res_print(int fd,const char * fmt,...)37 static void netdev_res_print(int fd, const char *fmt, ...)
38 {
39     va_list  args;
40 
41     va_start(args, fmt);
42     memset(netdev_res_print_buffer, 0, NDEV_PRINT_BUFFER_SIZE);
43     vsprintf(netdev_res_print_buffer, fmt, args);
44     va_end(args);
45 
46     if (fd >= 0) {
47         write(fd, netdev_res_print_buffer, strlen(netdev_res_print_buffer));
48     } else {
49         NDEV_PRINT(netdev_res_print_buffer);
50     }
51 }
52 
netdev_list_if(int fd)53 static void netdev_list_if(int fd)
54 {
55 #define NETDEV_IFCONFIG_MAC_MAX_LEN    6
56 #define NETDEV_IFCONFIG_IEMI_MAX_LEN   8
57 
58     int index;
59     slist_t *node  = NULL;
60     struct netdev *netdev = NULL;
61     struct netdev *cur_netdev_list = netdev_list;
62 
63     if (cur_netdev_list == NULL)
64     {
65         NDEV_PRINT("ifconfig: network interface device list error.\n");
66         return;
67     }
68 
69     CPSR_ALLOC();
70     RHINO_CPU_INTRPT_DISABLE();
71 
72     slist_for_each_entry_safe(&(netdev_list->list), node, netdev, struct netdev, list)
73     {
74         /* line 1 */
75         netdev_res_print(fd, "%-10s", netdev->name);
76         netdev_res_print(fd, "HWaddr ");
77 		    /* 6 - MAC address, 8 - IEMI */
78         if (netdev->hwaddr_len == NETDEV_IFCONFIG_MAC_MAX_LEN)
79         {
80             for (index = 0; index < netdev->hwaddr_len; index++)
81             {
82                 netdev_res_print(fd, "%02x ", netdev->hwaddr[index]);
83             }
84         }
85         else if (netdev->hwaddr_len == NETDEV_IFCONFIG_IEMI_MAX_LEN)
86         {
87             for (index = 0; index < netdev->hwaddr_len; index++)
88             {
89                 /* two numbers are displayed at one time*/
90                 if (netdev->hwaddr[index] < 10 && index != netdev->hwaddr_len - 1)
91                     netdev_res_print(fd, "0");
92 
93                 netdev_res_print(fd, "%d", netdev->hwaddr[index]);
94             }
95         }
96 		netdev_res_print(fd, " %s\n",(netdev == netdev_default)?"(Default)":"");
97 
98 		/* line 2 */
99 		netdev_res_print(fd, "          inet addr:%s", inet_ntoa(netdev->ip_addr));
100 		//NDEV_PRINT("  Bcast:");
101 		netdev_res_print(fd, "  Mask:%s", inet_ntoa(netdev->netmask));
102 	    netdev_res_print(fd, "\n");
103 
104 		/* line 3 */
105 		netdev_res_print(fd, "          Gateway:%s", inet_ntoa(netdev->gw));
106 		for (index = 0; index < NETDEV_DNS_SERVERS_NUM; index++)
107         {
108             netdev_res_print(fd, "  DNS %d: %s", index+1, inet_ntoa(netdev->dns_servers[index]));
109         }
110 		netdev_res_print(fd, "\n");
111 
112 		/* line 4 */
113 		netdev_res_print(fd, "         ");
114 		if (netdev->flags & NETDEV_FLAG_UP) netdev_res_print(fd, " UP");
115         else netdev_res_print(fd, " DOWN");
116         if (netdev->flags & NETDEV_FLAG_LINK_UP) netdev_res_print(fd, " LINK_UP");
117         else netdev_res_print(fd, " LINK_DOWN");
118         if (netdev->flags & NETDEV_FLAG_INTERNET_UP) netdev_res_print(fd, " INTERNET_UP");
119         else netdev_res_print(fd, " INTERNET_DOWN");
120         if (netdev->flags & NETDEV_FLAG_DHCP) netdev_res_print(fd, " DHCP_ENABLE");
121         else netdev_res_print(fd, " DHCP_DISABLE");
122         if (netdev->flags & NETDEV_FLAG_ETHARP) netdev_res_print(fd, " ETHARP");
123         if (netdev->flags & NETDEV_FLAG_BROADCAST) netdev_res_print(fd, " BROADCAST");
124         if (netdev->flags & NETDEV_FLAG_IGMP) netdev_res_print(fd, " IGMP");
125 		netdev_res_print(fd, "  MTU:%d", netdev->mtu);
126 		netdev_res_print(fd, "\n");
127 /* Removed by chen_shiyu@anyka.oa */
128 #if 0
129         NDEV_PRINT("network interface device: %s%s\n",
130                    netdev->name,
131                    (netdev == netdev_default)?" (Default)":"");
132         NDEV_PRINT("MTU: %d\n", netdev->mtu);
133 
134         /* 6 - MAC address, 8 - IEMI */
135         if (netdev->hwaddr_len == NETDEV_IFCONFIG_MAC_MAX_LEN)
136         {
137             NDEV_PRINT("MAC: ");
138             for (index = 0; index < netdev->hwaddr_len; index++)
139             {
140                 NDEV_PRINT("%02x ", netdev->hwaddr[index]);
141             }
142         }
143         else if (netdev->hwaddr_len == NETDEV_IFCONFIG_IEMI_MAX_LEN)
144         {
145             NDEV_PRINT("IEMI: ");
146             for (index = 0; index < netdev->hwaddr_len; index++)
147             {
148                 /* two numbers are displayed at one time*/
149                 if (netdev->hwaddr[index] < 10 && index != netdev->hwaddr_len - 1)
150                     NDEV_PRINT("0");
151 
152                 NDEV_PRINT("%d", netdev->hwaddr[index]);
153             }
154         }
155 
156         NDEV_PRINT("\nFLAGS:");
157         if (netdev->flags & NETDEV_FLAG_UP) NDEV_PRINT(" UP");
158         else NDEV_PRINT(" DOWN");
159         if (netdev->flags & NETDEV_FLAG_LINK_UP) NDEV_PRINT(" LINK_UP");
160         else NDEV_PRINT(" LINK_DOWN");
161         if (netdev->flags & NETDEV_FLAG_INTERNET_UP) NDEV_PRINT(" INTERNET_UP");
162         else NDEV_PRINT(" INTERNET_DOWN");
163         if (netdev->flags & NETDEV_FLAG_DHCP) NDEV_PRINT(" DHCP_ENABLE");
164         else NDEV_PRINT(" DHCP_DISABLE");
165         if (netdev->flags & NETDEV_FLAG_ETHARP) NDEV_PRINT(" ETHARP");
166         if (netdev->flags & NETDEV_FLAG_BROADCAST) NDEV_PRINT(" BROADCAST");
167         if (netdev->flags & NETDEV_FLAG_IGMP) NDEV_PRINT(" IGMP");
168         NDEV_PRINT("\n");
169         NDEV_PRINT("ip address: %s\n", inet_ntoa(netdev->ip_addr));
170         NDEV_PRINT("gw address: %s\n", inet_ntoa(netdev->gw));
171         NDEV_PRINT("net mask  : %s\n", inet_ntoa(netdev->netmask));
172 
173         for (index = 0; index < NETDEV_DNS_SERVERS_NUM; index++)
174         {
175             NDEV_PRINT("dns server #%d: %s\n", index, inet_ntoa(netdev->dns_servers[index]));
176         }
177 #endif
178 
179         if (node && node->next)
180         {
181             netdev_res_print(fd, "\n");
182         }
183     }
184 
185     RHINO_CPU_INTRPT_ENABLE();
186 }
187 
netdev_set_if(char * netdev_name,char * ip_addr,char * gw_addr,char * nm_addr)188 static void netdev_set_if(char* netdev_name, char* ip_addr, char* gw_addr, char* nm_addr)
189 {
190     struct netdev *netdev = NULL;
191     ip_addr_t addr;
192 
193     netdev = netdev_get_by_name(netdev_name);
194     if (netdev == NULL)
195     {
196         LOGE(TAG, "bad network interface device name(%s).\n", netdev_name);
197         return;
198     }
199 
200     /* set IP address */
201     if ((ip_addr != NULL) && inet_aton(ip_addr, &addr))
202     {
203         netdev_set_ipaddr(netdev, &addr);
204     }
205 
206     /* set gateway address */
207     if ((gw_addr != NULL) && inet_aton(gw_addr, &addr))
208     {
209         netdev_set_gw(netdev, &addr);
210     }
211 
212     /* set netmask address */
213     if ((nm_addr != NULL) && inet_aton(nm_addr, &addr))
214     {
215         netdev_set_netmask(netdev, &addr);
216     }
217 }
218 
add_fd_info(struct netdev * netdev,int fd)219 static int add_fd_info(struct netdev* netdev, int fd)
220 {
221     netdev_fd_info_t* cur;
222 
223     cur = malloc(sizeof(netdev_fd_info_t));
224     if(cur == NULL) {
225         return -1;
226     }
227     memset(cur, 0, sizeof(netdev_fd_info_t));
228 
229     cur->fd = fd;
230     cur->netdev = netdev;
231 
232     slist_add_tail(&cur->next, &g_netdev_fd_list_head);
233 
234     return 0;
235 }
236 
del_fd_by_netdev(struct netdev * netdev)237 static int del_fd_by_netdev(struct netdev* netdev)
238 {
239     netdev_fd_info_t* cur;
240     int found = 0;
241 
242     slist_for_each_entry(&g_netdev_fd_list_head, cur, netdev_fd_info_t, next) {
243         if(cur->netdev == netdev) {
244             found = 1;
245             break;
246         }
247     }
248 
249     if(1 == found) {
250         slist_del(&cur->next, &g_netdev_fd_list_head);
251         return 0;
252     } else {
253         return -1;
254     }
255 }
256 
get_fd_by_netdev(struct netdev * netdev)257 static int get_fd_by_netdev(struct netdev* netdev)
258 {
259     netdev_fd_info_t* cur;
260     int found = 0;
261 
262     slist_for_each_entry(&g_netdev_fd_list_head, cur, netdev_fd_info_t, next) {
263         if(cur->netdev == netdev) {
264             found = 1;
265             break;
266         }
267     }
268 
269     if(1 == found) {
270         return cur->fd;
271     } else {
272         return -1;
273     }
274 }
275 extern int netdev_dhcpd_enabled(struct netdev *netdev, bool is_enabled);
276 
netdev_ifconfig(char * pwbuf,int blen,int argc,char ** argv)277 void netdev_ifconfig(char *pwbuf, int blen, int argc, char **argv)
278 {
279     char usage[] = "usage:  \r\n"
280                    "  ifconfig <eth0|wlan0> <up|down> \r\n"
281                    "eg:\r\n"
282                    "  1.enable ethernet:\r\n"
283                    "    ifconfig eth0 up\r\n\r\n"
284                    "  2.disable ethernet:\r\n"
285                    "    ifconfig eth0 down\r\n";
286 
287     char dev_name[32];
288 
289     if ((argc == 1) || (!strcmp(argv[1], ">") && argc == 3))
290     {
291         int fd = -1;
292         if (argc == 3) {
293             fd = open(argv[2], O_RDWR | O_CREAT);
294         }
295         netdev_list_if(fd);
296         if (fd >= 0) {
297             close(fd);
298         }
299 		return ;
300     }
301 
302 	if (strcmp(argv[1], "-h") == 0 || strcmp(argv[1], "help") == 0)
303 	{
304 		NDEV_PRINT("%s \n", usage);
305 		return ;
306 	}
307 
308 	struct netdev * dev = NULL;
309 	dev = netdev_get_by_name(argv[1]);
310 	if(!dev)
311 	{
312 		NDEV_PRINT("can't find %s !\n", argv[1]);
313 		return ;
314 	}
315 
316 	if (argc == 3)
317     {
318         if (strcmp(argv[2], "up") == 0)
319         {
320             int fd = -1;
321 
322             fd = get_fd_by_netdev(dev);
323             if((fd != -1) && (!netdev_is_up(dev))) {
324                 del_fd_by_netdev(dev);
325                 fd = -1;
326             }
327 
328             if(fd == -1) {
329                 snprintf(dev_name, sizeof(dev_name), "/dev/%s", argv[1]);
330                 if((fd = open(dev_name, O_RDWR)) < 0)
331             {
332                 NDEV_PRINT("open %s fail !\n",argv[1]);
333                 return ;
334             }
335             netdev_set_up(dev);
336                 add_fd_info(dev, fd);
337             } else {
338                 NDEV_PRINT("%s is already up\n",argv[1]);
339             }
340         }
341         else if (strcmp(argv[2], "down") == 0)
342         {
343             int fd = -1;
344 
345             fd = get_fd_by_netdev(dev);
346             if(fd != -1) {
347                 del_fd_by_netdev(dev);
348                 close(fd);
349                 fd = -1;
350             }
351 
352             if(netdev_is_up(dev)) {
353                 netdev_set_down(dev);
354             } else {
355                 NDEV_PRINT("%s is already down\n",argv[1]);
356             }
357         }
358         else if (strcmp(argv[2], "def") == 0)
359         {
360             netdev_set_default(dev);
361         }
362         else
363         {
364             NDEV_PRINT("Invalid argument: %s\n", argv[1]);
365         }
366     }
367 	else if(argc == 4 && strcmp(argv[2], "dhcp") == 0)
368 	{
369 		if(strcmp(argv[3], "on") == 0)
370 		{
371 			netdev_dhcp_enabled(dev, true);
372 		}
373 		else if(strcmp(argv[3], "off") == 0)
374 		{
375 			netdev_dhcp_enabled(dev, false);
376 		}
377 	}
378     else if(argc == 4 && strcmp(argv[2], "dhcpd") == 0)
379     {
380         if(strcmp(argv[3], "on") == 0)
381         {
382             netdev_dhcpd_enabled(dev, true);
383         }
384         else if(strcmp(argv[3], "off") == 0)
385         {
386             netdev_dhcpd_enabled(dev, false);
387         }
388     }
389     else if (argc == 5)
390     {
391         NDEV_PRINT("config : %s\n", argv[1]);
392         NDEV_PRINT("IP addr: %s\n", argv[2]);
393         NDEV_PRINT("Gateway: %s\n", argv[3]);
394         NDEV_PRINT("netmask: %s\n", argv[4]);
395         netdev_set_if(argv[1], argv[2], argv[3], argv[4]);
396     }
397     else
398     {
399         LOGE(TAG, "bad parameter! \n %s \n", usage);
400     }
401 }
402 
403 static struct cli_command ifconfig_cmd = {
404     .name     = "ifconfig",
405     .help     = "list the information of all network interfaces",
406     .function = netdev_ifconfig,
407 };
408 
netdev_cmd_ping(char * target_name,uint32_t times,size_t size,int fd)409 static int netdev_cmd_ping(char* target_name, uint32_t times, size_t size, int fd)
410 {
411 #define NETDEV_PING_DATA_SIZE       32
412 /** ping receive timeout - in milliseconds */
413 #define NETDEV_PING_RECV_TIMEO      2000 //(2 * RT_TICK_PER_SECOND)
414 /** ping delay - in milliseconds */
415 #define NETDEV_PING_DELAY           1000 //(1 * RT_TICK_PER_SECOND)
416 /* check netdev ping options */
417 #define NETDEV_PING_IS_COMMUNICABLE(netdev) \
418     ((netdev) && (netdev)->ops && (netdev)->ops->ping && \
419         netdev_is_up(netdev) && netdev_is_link_up(netdev)) \
420 
421     struct netdev *netdev = NULL;
422     struct netdev_ping_resp ping_resp;
423     uint32_t index, ret = 0;
424     uint32_t resp_cnt = 0;
425     //rt_tick_t start_time = rt_tick_get();
426     uint64_t start_time = aos_now_ms();
427 	uint64_t min_us=0,avg_us=0,max_us=0,mdev_us=0,sum_us=0;
428 	uint64_t d_sum = 0;
429 
430     if (size == 0)
431     {
432         size = NETDEV_PING_DATA_SIZE;
433     }
434 
435     if (NETDEV_PING_IS_COMMUNICABLE(netdev_default))
436     {
437         /* using default network interface device for ping */
438         netdev = netdev_default;
439     }
440     else
441     {
442         /* using first internet up status network interface device */
443         netdev = netdev_get_first_by_flags(NETDEV_FLAG_LINK_UP);
444         printf("%s,%d, netdev %p, (netdev)->ops %p, (netdev)->ops->ping %p, is_up %d, is_link_up %d\r\n",
445                 __func__,__LINE__,netdev,(netdev)->ops, (netdev)->ops->ping, netdev_is_up(netdev),
446                 netdev_is_link_up(netdev));
447         if (netdev == NULL || NETDEV_PING_IS_COMMUNICABLE(netdev) == 0)
448         {
449             LOGE(TAG, "ping: network interface device get error.\n");
450             return -1;
451         }
452     }
453 
454     for (index = 0; index < times; index++)
455     {
456         memset(&ping_resp, 0x00, sizeof(struct netdev_ping_resp));
457         ret = netdev->ops->ping(netdev, (const char *)target_name, size, NETDEV_PING_RECV_TIMEO, &ping_resp);
458         if (ret == -2)
459         {
460             netdev_res_print(fd, "ping: from %s icmp_seq=%d timeout\n",
461                 (ip_addr_isany(&(ping_resp.ip_addr))) ? target_name : inet_ntoa(ping_resp.ip_addr), index);
462         }
463         else if (ret == -1)
464         {
465             netdev_res_print(fd, "ping: unknown %s %s\n",
466                 (ip_addr_isany(&(ping_resp.ip_addr))) ? "host" : "address",
467                 (ip_addr_isany(&(ping_resp.ip_addr))) ? target_name : inet_ntoa(ping_resp.ip_addr));
468         }
469         else
470         {
471             resp_cnt++;
472 			sum_us += ping_resp.ticks;
473 			d_sum += ping_resp.ticks * ping_resp.ticks;
474 
475 			if(ping_resp.ticks > max_us || max_us == 0)
476 				max_us = ping_resp.ticks;
477 
478 			if(ping_resp.ticks < min_us || min_us == 0)
479 				min_us = ping_resp.ticks;
480 
481             if (ping_resp.ttl == 0)
482             {
483                 netdev_res_print(fd, "%d bytes from %s icmp_seq=%d time=%lld ms\n",
484                             ping_resp.data_len, inet_ntoa(ping_resp.ip_addr), index, ping_resp.ticks);
485             }
486             else
487             {
488                 netdev_res_print(fd, "%d bytes from %s icmp_seq=%d ttl=%d time=%d.%03d ms\n",
489                             ping_resp.data_len, inet_ntoa(ping_resp.ip_addr), index, ping_resp.ttl, (int)ping_resp.ticks/1000,(int)ping_resp.ticks%1000);
490 
491             }
492         }
493         aos_msleep(NETDEV_PING_DELAY);
494     }
495 
496 	//int time = (int)(rt_tick_get() - start_time) * 5 - NETDEV_PING_DELAY;
497 	int time = (int)(aos_now_ms() - start_time) - NETDEV_PING_DELAY;
498     netdev_res_print(fd, "\n--- %s ping %s statistics --- \n",netdev->name,target_name);
499 	netdev_res_print(fd, "%d packets transmitted, %d packets received, %d%s packets lost, time %d ms\n", \
500 		times, resp_cnt,(int)((times - resp_cnt)*100/times),"%",time);
501 
502     if(resp_cnt != 0) {
503 	    avg_us = sum_us/resp_cnt;
504 
505 	    //mdev = sqrt(sum(rtt^2)/n - (sum(rtt)/n)^2)
506 	    mdev_us = sqrt(d_sum / resp_cnt - avg_us * avg_us);
507     }
508 	netdev_res_print(fd, "min/avg/max/mdev = %d.%03d/%d.%03d/%d.%03d/%d.%03d ms \n",
509 		(int)min_us/1000, (int)min_us%1000,(int)avg_us/1000,(int)avg_us%1000,(int)max_us/1000,(int)max_us%1000,(int)mdev_us/1000,(int)mdev_us%1000);
510 
511     return 0;
512 }
513 
netdev_ping(char * pwbuf,int blen,int argc,char ** argv)514 void netdev_ping(char *pwbuf, int blen, int argc, char **argv)
515 {
516     uint32_t times = 10;
517     int size = 32;
518     int i;
519 	char ping_usage[] = "usage:\n\t ping <host address> [-c count] [-s packetssize] \
520     \n\t e.g:\n\t ping 192.168.1.1 -s 1400 \n\t ping 192.168.1.1 -c 0 (run forerver) \n";
521     int fd = -1;
522 
523     if (argc == 1 || (strcmp(argv[1], "-h") == 0))
524     {
525         NDEV_PRINT("%s\n", ping_usage);
526 		return ;
527     }
528 //add by li_zhihai@any.oa
529     if(argc >= 2)
530     {
531         for (i = 2 ; i < argc; i++)
532         {
533             if(strcmp(argv[i], "-c") == 0)
534             {
535                 i++;
536                 if(argv[i] == NULL)
537                     NDEV_PRINT("%s \n",ping_usage);
538                 else
539                     times = atoi(argv[i]) > 0 ? atoi(argv[i]) : 0xffffffff;
540 
541             }else if(strcmp(argv[i], "-s") == 0)
542             {
543                 i++;
544                 if(argv[i] == NULL)
545                     NDEV_PRINT("%s \n",ping_usage);
546                 else
547                     size = atoi(argv[i]);
548             }else if(strcmp(argv[i], ">") == 0)
549             {
550                 i++;
551 
552                 if (fd >= 0) {
553                     close(fd);
554                 }
555 
556                 fd = open(argv[i], O_RDWR | O_CREAT);
557             }
558             else
559             {
560                 NDEV_PRINT("invalid para:[%s]\n %s \n", argv[i], ping_usage);
561                 if (fd >= 0) {
562                     close(fd);
563                 }
564 				return ;
565             }
566         }
567         //NDEV_PRINT("ping times = %d, size = %d \n", times, size);
568 //end add
569         netdev_cmd_ping(argv[1], times, size, fd);
570 
571         if (fd >= 0) {
572             close(fd);
573         }
574     }
575 }
576 static struct cli_command ping_cmd = {
577     .name     = "ping",
578     .help     = "ping network host",
579     .function = netdev_ping,
580 };
581 
netdev_list_dns(void)582 static void netdev_list_dns(void)
583 {
584     int index = 0;
585     struct netdev *netdev = NULL;
586     slist_t *node  = NULL;
587 
588     CPSR_ALLOC();
589     RHINO_CPU_INTRPT_DISABLE();
590 
591     slist_for_each_entry_safe(&(netdev_list->list), node, netdev, struct netdev, list)
592     {
593         NDEV_PRINT("network interface device: %s%s\n",
594                 netdev->name,
595                 (netdev == netdev_default)?" (Default)":"");
596 
597         for(index = 0; index < NETDEV_DNS_SERVERS_NUM; index++)
598         {
599             NDEV_PRINT("dns server #%d: %s\n", index, inet_ntoa(netdev->dns_servers[index]));
600         }
601 
602         if (node && node->next)
603         {
604             NDEV_PRINT("\n");
605         }
606     }
607 
608     RHINO_CPU_INTRPT_ENABLE();
609 }
610 
netdev_set_dns(char * netdev_name,uint8_t dns_num,char * dns_server)611 static void netdev_set_dns(char *netdev_name, uint8_t dns_num, char *dns_server)
612 {
613     struct netdev *netdev = NULL;
614     ip_addr_t dns_addr;
615 
616     netdev = netdev_get_by_name(netdev_name);
617     if (netdev == NULL)
618     {
619         NDEV_PRINT("bad network interface device name(%s).\n", netdev_name);
620         return;
621     }
622 
623     if ((dns_server != NULL) && inet_aton(dns_server, &dns_addr)) {
624         netdev_set_dns_server(netdev, dns_num, &dns_addr);
625     }
626 
627     NDEV_PRINT("set network interface device(%s) dns server #0: %s\n", netdev_name, dns_server);
628 }
629 
netdev_dns(char * pwbuf,int blen,int argc,char ** argv)630 void netdev_dns(char *pwbuf, int blen, int argc, char **argv)
631 {
632     if (argc == 1)
633     {
634         netdev_list_dns();
635     }
636     else if (argc == 3)
637     {
638         netdev_set_dns(argv[1], 0, argv[2]);
639     }
640     else if (argc == 4)
641     {
642         netdev_set_dns(argv[1], atoi(argv[2]), argv[3]);
643     }
644     else
645     {
646         NDEV_PRINT("bad parameter! input: dns <netdev_name> [dns_num] <dns_server>\n");
647     }
648 }
649 
650 static struct cli_command dns_cmd = {
651     .name     = "dns",
652     .help     = "list and set the information of dns",
653     .function = netdev_dns,
654 };
655 
netdev_cmd_netstat(void)656 static void netdev_cmd_netstat(void)
657 {
658     slist_t *node  = NULL;
659     struct netdev *netdev = NULL;
660     struct netdev *cur_netdev_list = netdev_list;
661 
662     if (cur_netdev_list == NULL)
663     {
664         NDEV_PRINT("netstat: network interface device list error.\n");
665         return;
666     }
667 
668     CPSR_ALLOC();
669     RHINO_CPU_INTRPT_DISABLE();
670 
671     slist_for_each_entry_safe(&(netdev_list->list), node, netdev, struct netdev, list)
672     {
673         if (netdev && netdev->ops && netdev->ops->netstat)
674         {
675             break;
676         }
677     }
678 
679     RHINO_CPU_INTRPT_ENABLE();
680     if(netdev && netdev->ops) {
681         netdev->ops->netstat(netdev);
682     }
683 }
684 
netdev_netstat(char * pwbuf,int blen,int argc,char ** argv)685 void netdev_netstat(char *pwbuf, int blen, int argc, char **argv)
686 {
687     if (argc != 1)
688     {
689         NDEV_PRINT("Please input: netstat \n");
690     }
691     else
692     {
693         netdev_cmd_netstat();
694     }
695 }
696 
697 static struct cli_command netstat_cmd = {
698     .name     = "netstat",
699     .help     = "list the information of TCP/IP",
700     .function = netdev_netstat,
701 };
702 
netdev_cli_register(void)703 void netdev_cli_register(void)
704 {
705     aos_cli_register_command(&ifconfig_cmd);
706     aos_cli_register_command(&ping_cmd);
707     aos_cli_register_command(&dns_cmd);
708     aos_cli_register_command(&netstat_cmd);
709 }
710