10d163575Sopenharmony_ci/* 20d163575Sopenharmony_ci * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. 30d163575Sopenharmony_ci * Copyright (c) 2020-2022 Huawei Device Co., Ltd. All rights reserved. 40d163575Sopenharmony_ci * 50d163575Sopenharmony_ci * Redistribution and use in source and binary forms, with or without modification, 60d163575Sopenharmony_ci * are permitted provided that the following conditions are met: 70d163575Sopenharmony_ci * 80d163575Sopenharmony_ci * 1. Redistributions of source code must retain the above copyright notice, this list of 90d163575Sopenharmony_ci * conditions and the following disclaimer. 100d163575Sopenharmony_ci * 110d163575Sopenharmony_ci * 2. Redistributions in binary form must reproduce the above copyright notice, this list 120d163575Sopenharmony_ci * of conditions and the following disclaimer in the documentation and/or other materials 130d163575Sopenharmony_ci * provided with the distribution. 140d163575Sopenharmony_ci * 150d163575Sopenharmony_ci * 3. Neither the name of the copyright holder nor the names of its contributors may be used 160d163575Sopenharmony_ci * to endorse or promote products derived from this software without specific prior written 170d163575Sopenharmony_ci * permission. 180d163575Sopenharmony_ci * 190d163575Sopenharmony_ci * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 200d163575Sopenharmony_ci * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 210d163575Sopenharmony_ci * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 220d163575Sopenharmony_ci * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 230d163575Sopenharmony_ci * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 240d163575Sopenharmony_ci * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 250d163575Sopenharmony_ci * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 260d163575Sopenharmony_ci * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 270d163575Sopenharmony_ci * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 280d163575Sopenharmony_ci * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 290d163575Sopenharmony_ci * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 300d163575Sopenharmony_ci */ 310d163575Sopenharmony_ci 320d163575Sopenharmony_ci#include "../core/ipv4/etharp.c" /* for arp_table */ 330d163575Sopenharmony_ci#define icmp6_hdr netinet_icmp6_hdr 340d163575Sopenharmony_ci#include <netinet/icmp6.h> 350d163575Sopenharmony_ci#undef icmp6_hdr 360d163575Sopenharmony_ci#include "lwip/fixme.h" 370d163575Sopenharmony_ci#include "lwip/opt.h" 380d163575Sopenharmony_ci 390d163575Sopenharmony_ci#if LWIP_ENABLE_LOS_SHELL_CMD 400d163575Sopenharmony_ci#include "lwip/api.h" 410d163575Sopenharmony_ci#include "lwip/tcpip.h" 420d163575Sopenharmony_ci#include "lwip/netif.h" 430d163575Sopenharmony_ci#include "lwip/netdb.h" 440d163575Sopenharmony_ci#include "lwip/stats.h" 450d163575Sopenharmony_ci#include "lwip/err.h" 460d163575Sopenharmony_ci#include "lwip/inet.h" 470d163575Sopenharmony_ci#include "netif/etharp.h" 480d163575Sopenharmony_ci#include "lwip/ip_addr.h" 490d163575Sopenharmony_ci#include "lwip/ip6_addr.h" 500d163575Sopenharmony_ci#include "lwip/icmp.h" 510d163575Sopenharmony_ci#include "lwip/priv/nd6_priv.h" 520d163575Sopenharmony_ci#include "lwip/sockets.h" 530d163575Sopenharmony_ci#include "lwip/inet_chksum.h" 540d163575Sopenharmony_ci#include "lwip/raw.h" 550d163575Sopenharmony_ci#include "los_config.h" 560d163575Sopenharmony_ci#include <string.h> 570d163575Sopenharmony_ci#include "limits.h" 580d163575Sopenharmony_ci#include <stdlib.h> 590d163575Sopenharmony_ci#include <stdio.h> 600d163575Sopenharmony_ci#include <errno.h> 610d163575Sopenharmony_ci#include <time.h> 620d163575Sopenharmony_ci#include <ctype.h> 630d163575Sopenharmony_ci#include <poll.h> 640d163575Sopenharmony_ci 650d163575Sopenharmony_ci#include "lwip/api_shell.h" 660d163575Sopenharmony_ci 670d163575Sopenharmony_ci#include "lwip/dns.h" 680d163575Sopenharmony_ci#include "lwip/udp.h" 690d163575Sopenharmony_ci#include "lwip/priv/tcp_priv.h" 700d163575Sopenharmony_ci 710d163575Sopenharmony_ci#include "lwip/dhcp.h" 720d163575Sopenharmony_ci#include "lwip/netifapi.h" 730d163575Sopenharmony_ci#include "los_strnlen_user.h" 740d163575Sopenharmony_ci#include "linux/kernel.h" 750d163575Sopenharmony_ci#ifdef LOSCFG_SHELL 760d163575Sopenharmony_ci#include "shcmd.h" 770d163575Sopenharmony_ci#include "shell.h" 780d163575Sopenharmony_ci#endif 790d163575Sopenharmony_ci 800d163575Sopenharmony_ci#define LWIP_STATIC static 810d163575Sopenharmony_ci 820d163575Sopenharmony_ci#if LWIP_ARP 830d163575Sopenharmony_ciextern sys_sem_t ip_conflict_detect; 840d163575Sopenharmony_ci#endif 850d163575Sopenharmony_ciextern volatile int tcpip_init_finish; 860d163575Sopenharmony_ciextern const char *const tcp_state_str[]; 870d163575Sopenharmony_ciextern int get_unused_socket_num(void); 880d163575Sopenharmony_ci 890d163575Sopenharmony_ci#if LWIP_IPV6 900d163575Sopenharmony_ci#define LWIP_MAX_PING6_ARG_COUNT 64 910d163575Sopenharmony_ci#define LWIP_PING6_STANDARD_PKT_SIZE 56 920d163575Sopenharmony_ci#define LWIP_PING6_STARTING_SEQ_NUM 0x2255 930d163575Sopenharmony_ci#define LWIP_PING6_OUT_OF_ORDER_MAGNITUDE 1 940d163575Sopenharmony_ci 950d163575Sopenharmony_ci#define LWIP_PING6_COUNT_ARG 1 960d163575Sopenharmony_ci#define LWIP_PING6_SOURCE_ADDRESS_ARG 2 970d163575Sopenharmony_ci#define LWIP_PING6_INTERFACE_ARG 4 980d163575Sopenharmony_ci#define LWIP_PING6_HOSTNAME_ARG 8 990d163575Sopenharmony_ci#define LWIP_PING6_DEFAULT_SOCKET 16 1000d163575Sopenharmony_ci#endif 1010d163575Sopenharmony_ci 1020d163575Sopenharmony_ci/* Forward Declarations [START] */ 1030d163575Sopenharmony_ci#ifndef LWIP_TESTBED 1040d163575Sopenharmony_ciLWIP_STATIC 1050d163575Sopenharmony_ci#endif 1060d163575Sopenharmony_ciint print_netif(struct netif *netif, char *print_buf, unsigned int buf_len); 1070d163575Sopenharmony_ci 1080d163575Sopenharmony_ci#ifndef LWIP_TESTBED 1090d163575Sopenharmony_ciLWIP_STATIC 1100d163575Sopenharmony_ci#endif 1110d163575Sopenharmony_civoid lwip_ifconfig_show_internal(void *arg); 1120d163575Sopenharmony_ci 1130d163575Sopenharmony_ci#ifndef LWIP_TESTBED 1140d163575Sopenharmony_ciLWIP_STATIC 1150d163575Sopenharmony_ci#endif 1160d163575Sopenharmony_civoid lwip_ifconfig_internal(void *arg); 1170d163575Sopenharmony_ci 1180d163575Sopenharmony_civoid lwip_printsize(size_t size); 1190d163575Sopenharmony_ciLWIP_STATIC void lwip_ifconfig_usage(const char *cmd); 1200d163575Sopenharmony_ci 1210d163575Sopenharmony_ci#ifndef LWIP_TESTBED 1220d163575Sopenharmony_ciLWIP_STATIC 1230d163575Sopenharmony_ci#endif 1240d163575Sopenharmony_civoid lwip_arp_show_internal(struct netif *netif, char *printf_buf, unsigned int buf_len); 1250d163575Sopenharmony_ci 1260d163575Sopenharmony_ci#ifndef LWIP_TESTBED 1270d163575Sopenharmony_ciLWIP_STATIC 1280d163575Sopenharmony_ci#endif 1290d163575Sopenharmony_civoid lwip_arp_internal(void *arg); 1300d163575Sopenharmony_ci 1310d163575Sopenharmony_ciLWIP_STATIC void lwip_arp_usage(const char *cmd); 1320d163575Sopenharmony_civoid ifup_internal(void *arg); 1330d163575Sopenharmony_civoid ifdown_internal(void *arg); 1340d163575Sopenharmony_ci 1350d163575Sopenharmony_ci#if LWIP_DNS 1360d163575Sopenharmony_ciLWIP_STATIC unsigned int get_hostip(const char *hname); 1370d163575Sopenharmony_ci 1380d163575Sopenharmony_ci#ifndef LWIP_TESTBED 1390d163575Sopenharmony_ciLWIP_STATIC 1400d163575Sopenharmony_ci#endif 1410d163575Sopenharmony_cistruct hostent *gethostnameinfo(const char *host); 1420d163575Sopenharmony_ci 1430d163575Sopenharmony_ci#endif /* LWIP_DNS */ 1440d163575Sopenharmony_ci 1450d163575Sopenharmony_ci#ifdef LWIP_DEBUG_INFO 1460d163575Sopenharmony_ciLWIP_STATIC u32_t netdebug_memp(int argc, const char **argv); 1470d163575Sopenharmony_ciLWIP_STATIC u32_t netdebug_sock(int argc, const char **argv); 1480d163575Sopenharmony_ciu32_t osShellNetDebug(int argc, const char **argv); 1490d163575Sopenharmony_ciu32_t osShellIpDebug(int argc, const char **argv); 1500d163575Sopenharmony_ci#endif /* LWIP_DEBUG_INFO */ 1510d163575Sopenharmony_ci#if LWIP_IPV6 1520d163575Sopenharmony_ci/* Holds params for ping6 task */ 1530d163575Sopenharmony_citypedef struct ping6_args { 1540d163575Sopenharmony_ci u8_t args_found; 1550d163575Sopenharmony_ci u8_t interface_index; 1560d163575Sopenharmony_ci u8_t host_index; 1570d163575Sopenharmony_ci u8_t pad; 1580d163575Sopenharmony_ci u32_t pingcount; 1590d163575Sopenharmony_ci ip6_addr_t src_addr; 1600d163575Sopenharmony_ci ip6_addr_t dst_addr; 1610d163575Sopenharmony_ci} ping6_args_t; 1620d163575Sopenharmony_ci 1630d163575Sopenharmony_ci/* Holds stats for ongoing ping6 task */ 1640d163575Sopenharmony_citypedef struct ping6_stats { 1650d163575Sopenharmony_ci u32_t flag; 1660d163575Sopenharmony_ci u32_t min_rtt; 1670d163575Sopenharmony_ci u32_t max_rtt; 1680d163575Sopenharmony_ci float avg_rtt; 1690d163575Sopenharmony_ci} ping6_stats_t; 1700d163575Sopenharmony_ciLWIP_STATIC void update_ping6_stats(ping6_stats_t *ping6_stats, u32_t rtt, u32_t nreceived); 1710d163575Sopenharmony_ciLWIP_STATIC int parse_args_ping6(int argc, const char **argv, ping6_args_t *ping6_params); 1720d163575Sopenharmony_ci 1730d163575Sopenharmony_ciu32_t osShellPing6(int argc, const char **argv); 1740d163575Sopenharmony_ciLWIP_STATIC int create_ping6_socket(u8_t type, const void *param); 1750d163575Sopenharmony_ciLWIP_STATIC const char *convert_icmpv6_err_to_string(u8_t err_type); 1760d163575Sopenharmony_ci#endif /* LWIP_IPV6 */ 1770d163575Sopenharmony_ciu32_t osTcpserver(int argc, const char **argv); 1780d163575Sopenharmony_civoid udpserver(int argc, const char **argv); 1790d163575Sopenharmony_civoid tcp_access(int sockfd); 1800d163575Sopenharmony_ci#if LWIP_IPV6 1810d163575Sopenharmony_ciint netstat_get_udp_sendQLen6(struct udp_pcb *udppcb, struct pbuf *udpbuf); 1820d163575Sopenharmony_ciint netstat_udp_sendq6(struct udp_pcb *upcb); 1830d163575Sopenharmony_ci#endif 1840d163575Sopenharmony_ci#if LWIP_IPV4 1850d163575Sopenharmony_ciint netstat_get_udp_sendQLen(struct udp_pcb *udppcb, struct pbuf *udpbuf); 1860d163575Sopenharmony_ci#endif 1870d163575Sopenharmony_ciint netstat_tcp_sendq(struct tcp_pcb *tpcb); 1880d163575Sopenharmony_ciint netstat_tcp_recvq(struct tcp_pcb *tpcb); 1890d163575Sopenharmony_ciint netstat_netconn_recvq(const struct netconn *conn); 1900d163575Sopenharmony_ci 1910d163575Sopenharmony_ciint netstat_udp_sendq(struct udp_pcb *upcb); 1920d163575Sopenharmony_ciint netstat_netconn_sendq(struct netconn *conn); 1930d163575Sopenharmony_ci/* Forward Declarations [END] */ 1940d163575Sopenharmony_ci 1950d163575Sopenharmony_ci#define IFCONFIG_OPTION_SET_IP (1) 1960d163575Sopenharmony_ci#define IFCONFIG_OPTION_SET_NETMASK (1 << 1) 1970d163575Sopenharmony_ci#define IFCONFIG_OPTION_SET_GW (1 << 2) 1980d163575Sopenharmony_ci#define IFCONFIG_OPTION_SET_HW (1 << 3) 1990d163575Sopenharmony_ci#define IFCONFIG_OPTION_SET_UP (1 << 4) 2000d163575Sopenharmony_ci#define IFCONFIG_OPTION_SET_DOWN (1 << 5) 2010d163575Sopenharmony_ci#define IFCONFIG_OPTION_SET_MTU (1 << 6) 2020d163575Sopenharmony_ci#define IFCONFIG_OPTION_DEL_IP (1 << 7) 2030d163575Sopenharmony_ci 2040d163575Sopenharmony_ci#define NETSTAT_ENTRY_SIZE 120 2050d163575Sopenharmony_ci#define MAX_NETSTAT_ENTRY (NETSTAT_ENTRY_SIZE * (MEMP_NUM_TCP_PCB + MEMP_NUM_UDP_PCB + MEMP_NUM_TCP_PCB_LISTEN + 1)) 2060d163575Sopenharmony_ci 2070d163575Sopenharmony_ci#define PRINT_BUF_LEN 1024 2080d163575Sopenharmony_ci#define MAX_MACADDR_STRING_LENGTH 18 /* including NULL */ 2090d163575Sopenharmony_ci 2100d163575Sopenharmony_ci#define CONVERT_STRING_TO_HEX(_src, _dest) \ 2110d163575Sopenharmony_ci{ \ 2120d163575Sopenharmony_ci const char *_srcString = (char *)_src; \ 2130d163575Sopenharmony_ci _dest = 0; \ 2140d163575Sopenharmony_ci while (*_srcString) { \ 2150d163575Sopenharmony_ci _dest = (unsigned char)((_dest << 4) & 0xFF); \ 2160d163575Sopenharmony_ci if ((*_srcString >= 48) && (*_srcString <= 57)) /* between 0 to 9 */ \ 2170d163575Sopenharmony_ci _dest |= (unsigned char)(*_srcString - 48); \ 2180d163575Sopenharmony_ci else if ((*_srcString >= 65 && *_srcString <= 70)) /* between A to F */ \ 2190d163575Sopenharmony_ci _dest |= (unsigned char)((*_srcString - 65) + 10); \ 2200d163575Sopenharmony_ci else if ((*_srcString >= 97 && *_srcString <= 102)) /* between a to f */ \ 2210d163575Sopenharmony_ci _dest |= (unsigned char)((*_srcString - 97) + 10); \ 2220d163575Sopenharmony_ci else break; \ 2230d163575Sopenharmony_ci ++_srcString; \ 2240d163575Sopenharmony_ci } \ 2250d163575Sopenharmony_ci} 2260d163575Sopenharmony_ci 2270d163575Sopenharmony_ci#define ERR_IFCONFIG_STRING_PUT(ret, str) \ 2280d163575Sopenharmony_ci do { \ 2290d163575Sopenharmony_ci (ret) = snprintf_s(ifconfig_cmd->cb_print_buf + ifconfig_cmd->print_len, \ 2300d163575Sopenharmony_ci PRINT_BUF_LEN - ifconfig_cmd->print_len, \ 2310d163575Sopenharmony_ci ((PRINT_BUF_LEN - ifconfig_cmd->print_len) - 1), (str)); \ 2320d163575Sopenharmony_ci if (((ret) > 0) && ((unsigned int)(ret) < (PRINT_BUF_LEN - ifconfig_cmd->print_len))) \ 2330d163575Sopenharmony_ci ifconfig_cmd->print_len += (unsigned int)(ret); \ 2340d163575Sopenharmony_ci } while (0) \ 2350d163575Sopenharmony_ci 2360d163575Sopenharmony_ci#define LWIP_MSECS_TO_SECS(time_in_msecs) (time_in_msecs / 1000) 2370d163575Sopenharmony_cistruct ifconfig_option { 2380d163575Sopenharmony_ci char iface[IFNAMSIZ]; 2390d163575Sopenharmony_ci unsigned int option; 2400d163575Sopenharmony_ci ip_addr_t ip_addr; 2410d163575Sopenharmony_ci ip_addr_t netmask; 2420d163575Sopenharmony_ci ip_addr_t gw; 2430d163575Sopenharmony_ci unsigned char ethaddr[6]; 2440d163575Sopenharmony_ci u16_t mtu; 2450d163575Sopenharmony_ci /* when using telnet, print to the telnet socket will result in system */ 2460d163575Sopenharmony_ci /* deadlock. So we cache the print data to a buf, and when the tcpip */ 2470d163575Sopenharmony_ci /* callback returns, then print the data out to the telnet socket */ 2480d163575Sopenharmony_ci sys_sem_t cb_completed; 2490d163575Sopenharmony_ci char cb_print_buf[PRINT_BUF_LEN]; 2500d163575Sopenharmony_ci unsigned int print_len; 2510d163575Sopenharmony_ci}; 2520d163575Sopenharmony_ci 2530d163575Sopenharmony_cistruct netstat_data { 2540d163575Sopenharmony_ci s8_t *netstat_out_buf; 2550d163575Sopenharmony_ci u32_t netstat_out_buf_len; 2560d163575Sopenharmony_ci u32_t netstat_out_buf_updated_len; 2570d163575Sopenharmony_ci sys_sem_t cb_completed; 2580d163575Sopenharmony_ci}; 2590d163575Sopenharmony_ci 2600d163575Sopenharmony_cistruct if_cmd_data { 2610d163575Sopenharmony_ci char *if_name; 2620d163575Sopenharmony_ci err_t err; 2630d163575Sopenharmony_ci sys_sem_t cb_completed; 2640d163575Sopenharmony_ci}; 2650d163575Sopenharmony_ci 2660d163575Sopenharmony_ci#ifndef LWIP_TESTBED 2670d163575Sopenharmony_ciLWIP_STATIC 2680d163575Sopenharmony_ci#endif 2690d163575Sopenharmony_ciint print_netif(struct netif *netif, char *print_buf, unsigned int buf_len) 2700d163575Sopenharmony_ci{ 2710d163575Sopenharmony_ci int i, ret; 2720d163575Sopenharmony_ci char *tmp = print_buf; 2730d163575Sopenharmony_ci#if LWIP_IPV6 2740d163575Sopenharmony_ci char *addr = NULL; 2750d163575Sopenharmony_ci#endif 2760d163575Sopenharmony_ci#ifdef LOSCFG_NET_CONTAINER 2770d163575Sopenharmony_ci struct net_group *group = get_net_group_from_netif(netif); 2780d163575Sopenharmony_ci#endif 2790d163575Sopenharmony_ci if (buf_len < 1) { 2800d163575Sopenharmony_ci goto out; 2810d163575Sopenharmony_ci } 2820d163575Sopenharmony_ci if (netif->link_layer_type == LOOPBACK_IF) { 2830d163575Sopenharmony_ci ret = snprintf_s(tmp, buf_len, (buf_len - 1), "%.2s\t", netif->name); 2840d163575Sopenharmony_ci } else { 2850d163575Sopenharmony_ci ret = snprintf_s(tmp, buf_len, (buf_len - 1), "%s\t", netif_get_name(netif)); 2860d163575Sopenharmony_ci } 2870d163575Sopenharmony_ci if ((ret <= 0) || ((unsigned int)ret >= buf_len)) 2880d163575Sopenharmony_ci goto out; 2890d163575Sopenharmony_ci tmp += ret; 2900d163575Sopenharmony_ci buf_len -= (unsigned int)ret; 2910d163575Sopenharmony_ci#if LWIP_IPV4 2920d163575Sopenharmony_ci ret = snprintf_s(tmp, buf_len, (buf_len - 1), "ip:%s ", ipaddr_ntoa(&netif->ip_addr)); 2930d163575Sopenharmony_ci if ((ret <= 0) || ((unsigned int)ret >= buf_len)) 2940d163575Sopenharmony_ci goto out; 2950d163575Sopenharmony_ci tmp += ret; 2960d163575Sopenharmony_ci buf_len -= (unsigned int)ret; 2970d163575Sopenharmony_ci 2980d163575Sopenharmony_ci ret = snprintf_s(tmp, buf_len, (buf_len - 1), "netmask:%s ", ipaddr_ntoa(&netif->netmask)); 2990d163575Sopenharmony_ci if ((ret <= 0) || ((unsigned int)ret >= buf_len)) 3000d163575Sopenharmony_ci goto out; 3010d163575Sopenharmony_ci tmp += ret; 3020d163575Sopenharmony_ci buf_len -= (unsigned int)ret; 3030d163575Sopenharmony_ci 3040d163575Sopenharmony_ci ret = snprintf_s(tmp, buf_len, (buf_len - 1), "gateway:%s\n", ipaddr_ntoa(&netif->gw)); 3050d163575Sopenharmony_ci if ((ret <= 0) || ((unsigned int)ret >= buf_len)) 3060d163575Sopenharmony_ci goto out; 3070d163575Sopenharmony_ci tmp += ret; 3080d163575Sopenharmony_ci buf_len -= (unsigned int)ret; 3090d163575Sopenharmony_ci#endif 3100d163575Sopenharmony_ci 3110d163575Sopenharmony_ci#if LWIP_IPV6 3120d163575Sopenharmony_ci for (i = 0; i < LWIP_IPV6_NUM_ADDRESSES; i++) { 3130d163575Sopenharmony_ci /* only PREFERRED addresses are displyaed */ 3140d163575Sopenharmony_ci if (!ip6_addr_isvalid(netif->ip6_addr_state[i])) { 3150d163575Sopenharmony_ci continue; 3160d163575Sopenharmony_ci } 3170d163575Sopenharmony_ci addr = ip6addr_ntoa((const ip6_addr_t *)&netif->ip6_addr[i]); 3180d163575Sopenharmony_ci ret = snprintf_s(tmp, buf_len, (buf_len - 1), "\tip6: %s/64\n", addr ? addr : "::"); 3190d163575Sopenharmony_ci if ((ret <= 0) || ((unsigned int)ret >= buf_len)) 3200d163575Sopenharmony_ci goto out; 3210d163575Sopenharmony_ci tmp += ret; 3220d163575Sopenharmony_ci buf_len -= (unsigned int)ret; 3230d163575Sopenharmony_ci } 3240d163575Sopenharmony_ci#endif 3250d163575Sopenharmony_ci 3260d163575Sopenharmony_ci ret = snprintf_s(tmp, buf_len, (buf_len - 1), "\tHWaddr "); 3270d163575Sopenharmony_ci if ((ret <= 0) || ((unsigned int)ret >= buf_len)) 3280d163575Sopenharmony_ci goto out; 3290d163575Sopenharmony_ci tmp += ret; 3300d163575Sopenharmony_ci buf_len -= (unsigned int)ret; 3310d163575Sopenharmony_ci 3320d163575Sopenharmony_ci for (i = 0; i < netif->hwaddr_len - 1; i++) { 3330d163575Sopenharmony_ci ret = snprintf_s(tmp, buf_len, (buf_len - 1), "%02x:", netif->hwaddr[i]); 3340d163575Sopenharmony_ci if ((ret <= 0) || ((unsigned int)ret >= buf_len)) 3350d163575Sopenharmony_ci goto out; 3360d163575Sopenharmony_ci tmp += ret; 3370d163575Sopenharmony_ci buf_len -= (unsigned int)ret; 3380d163575Sopenharmony_ci } 3390d163575Sopenharmony_ci 3400d163575Sopenharmony_ci ret = snprintf_s(tmp, buf_len, (buf_len - 1), "%02x", netif->hwaddr[i]); 3410d163575Sopenharmony_ci if ((ret <= 0) || ((unsigned int)ret >= buf_len)) 3420d163575Sopenharmony_ci goto out; 3430d163575Sopenharmony_ci tmp += ret; 3440d163575Sopenharmony_ci buf_len -= (unsigned int)ret; 3450d163575Sopenharmony_ci 3460d163575Sopenharmony_ci ret = snprintf_s(tmp, buf_len, (buf_len - 1), " MTU:%d %s", netif->mtu, 3470d163575Sopenharmony_ci (netif->flags & NETIF_FLAG_UP) ? "Running" : "Stop"); 3480d163575Sopenharmony_ci if ((ret <= 0) || ((unsigned int)ret >= buf_len)) 3490d163575Sopenharmony_ci goto out; 3500d163575Sopenharmony_ci tmp += ret; 3510d163575Sopenharmony_ci buf_len -= (unsigned int)ret; 3520d163575Sopenharmony_ci 3530d163575Sopenharmony_ci#ifdef LOSCFG_NET_CONTAINER 3540d163575Sopenharmony_ci if ((group->netif_default == netif) && (netif_is_up(netif))) { 3550d163575Sopenharmony_ci#else 3560d163575Sopenharmony_ci if (netif_default == netif && netif_is_up(netif)) { 3570d163575Sopenharmony_ci#endif 3580d163575Sopenharmony_ci ret = snprintf_s(tmp, buf_len, (buf_len - 1), " %s", "Default"); 3590d163575Sopenharmony_ci if ((ret <= 0) || ((unsigned int)ret >= buf_len)) 3600d163575Sopenharmony_ci goto out; 3610d163575Sopenharmony_ci tmp += ret; 3620d163575Sopenharmony_ci buf_len -= (unsigned int)ret; 3630d163575Sopenharmony_ci } 3640d163575Sopenharmony_ci 3650d163575Sopenharmony_ci ret = snprintf_s(tmp, buf_len, (buf_len - 1), " %s\n", 3660d163575Sopenharmony_ci (netif->flags & NETIF_FLAG_LINK_UP) ? "Link UP" : "Link Down"); 3670d163575Sopenharmony_ci if ((ret <= 0) || ((unsigned int)ret >= buf_len)) 3680d163575Sopenharmony_ci goto out; 3690d163575Sopenharmony_ci tmp += ret; 3700d163575Sopenharmony_ci 3710d163575Sopenharmony_ci#if MIB2_STATS 3720d163575Sopenharmony_ci ret = snprintf_s(tmp, buf_len, (buf_len - 1), "\tRX packets:%u ", 3730d163575Sopenharmony_ci netif->mib2_counters.ifinucastpkts + netif->mib2_counters.ifinnucastpkts); 3740d163575Sopenharmony_ci if ((ret <= 0) || ((unsigned int)ret >= buf_len)) 3750d163575Sopenharmony_ci goto out; 3760d163575Sopenharmony_ci tmp += ret; 3770d163575Sopenharmony_ci buf_len -= (unsigned int)ret; 3780d163575Sopenharmony_ci 3790d163575Sopenharmony_ci ret = snprintf_s(tmp, buf_len, (buf_len - 1), "errors:%u ", netif->mib2_counters.ifinerrors); 3800d163575Sopenharmony_ci if ((ret <= 0) || ((unsigned int)ret >= buf_len)) 3810d163575Sopenharmony_ci goto out; 3820d163575Sopenharmony_ci tmp += ret; 3830d163575Sopenharmony_ci buf_len -= (unsigned int)ret; 3840d163575Sopenharmony_ci 3850d163575Sopenharmony_ci ret = snprintf_s(tmp, buf_len, (buf_len - 1), "dropped:%u ", netif->mib2_counters.ifindiscards); 3860d163575Sopenharmony_ci if ((ret <= 0) || ((unsigned int)ret >= buf_len)) 3870d163575Sopenharmony_ci goto out; 3880d163575Sopenharmony_ci tmp += ret; 3890d163575Sopenharmony_ci buf_len -= (unsigned int)ret; 3900d163575Sopenharmony_ci 3910d163575Sopenharmony_ci ret = snprintf_s(tmp, buf_len, (buf_len - 1), "overruns:%u\n", netif->mib2_counters.ifinoverruns); 3920d163575Sopenharmony_ci if ((ret <= 0) || ((unsigned int)ret >= buf_len)) 3930d163575Sopenharmony_ci goto out; 3940d163575Sopenharmony_ci tmp += ret; 3950d163575Sopenharmony_ci buf_len -= (unsigned int)ret; 3960d163575Sopenharmony_ci 3970d163575Sopenharmony_ci ret = snprintf_s(tmp, buf_len, (buf_len - 1), "\tTX packets:%u ", 3980d163575Sopenharmony_ci netif->mib2_counters.ifoutucastpkts + netif->mib2_counters.ifoutnucastpkts); 3990d163575Sopenharmony_ci if ((ret <= 0) || ((unsigned int)ret >= buf_len)) 4000d163575Sopenharmony_ci goto out; 4010d163575Sopenharmony_ci tmp += ret; 4020d163575Sopenharmony_ci buf_len -= (unsigned int)ret; 4030d163575Sopenharmony_ci 4040d163575Sopenharmony_ci ret = snprintf_s(tmp, buf_len, (buf_len - 1), "errors:%u ", netif->mib2_counters.ifouterrors); 4050d163575Sopenharmony_ci if ((ret <= 0) || ((unsigned int)ret >= buf_len)) 4060d163575Sopenharmony_ci goto out; 4070d163575Sopenharmony_ci tmp += ret; 4080d163575Sopenharmony_ci buf_len -= (unsigned int)ret; 4090d163575Sopenharmony_ci 4100d163575Sopenharmony_ci ret = snprintf_s(tmp, buf_len, (buf_len - 1), "dropped:%u\n", netif->mib2_counters.ifoutdiscards); 4110d163575Sopenharmony_ci if ((ret <= 0) || ((unsigned int)ret >= buf_len)) 4120d163575Sopenharmony_ci goto out; 4130d163575Sopenharmony_ci tmp += ret; 4140d163575Sopenharmony_ci buf_len -= (unsigned int)ret; 4150d163575Sopenharmony_ci 4160d163575Sopenharmony_ci ret = snprintf_s(tmp, buf_len, (buf_len - 1), "\tRX bytes:%u ", netif->mib2_counters.ifinoctets); 4170d163575Sopenharmony_ci if ((ret <= 0) || ((unsigned int)ret >= buf_len)) 4180d163575Sopenharmony_ci goto out; 4190d163575Sopenharmony_ci tmp += ret; 4200d163575Sopenharmony_ci buf_len -= (unsigned int)ret; 4210d163575Sopenharmony_ci 4220d163575Sopenharmony_ci ret = snprintf_s(tmp, buf_len, (buf_len - 1), "TX bytes:%u\n", netif->mib2_counters.ifoutoctets); 4230d163575Sopenharmony_ci if ((ret <= 0) || ((unsigned int)ret >= buf_len)) 4240d163575Sopenharmony_ci goto out; 4250d163575Sopenharmony_ci tmp += ret; 4260d163575Sopenharmony_ci buf_len -= (unsigned int)ret; 4270d163575Sopenharmony_ci#endif 4280d163575Sopenharmony_ci 4290d163575Sopenharmony_ciout: 4300d163575Sopenharmony_ci return (int)(tmp - print_buf); 4310d163575Sopenharmony_ci} 4320d163575Sopenharmony_ci 4330d163575Sopenharmony_ci#ifndef LWIP_TESTBED 4340d163575Sopenharmony_ciLWIP_STATIC 4350d163575Sopenharmony_ci#endif 4360d163575Sopenharmony_civoid lwip_ifconfig_show_internal(void *arg) 4370d163575Sopenharmony_ci{ 4380d163575Sopenharmony_ci struct netif *netif = NULL; 4390d163575Sopenharmony_ci struct ifconfig_option *ifconfig_cmd = (struct ifconfig_option *)arg; 4400d163575Sopenharmony_ci int ret; 4410d163575Sopenharmony_ci#ifdef LOSCFG_NET_CONTAINER 4420d163575Sopenharmony_ci struct net_group *group = get_curr_process_net_group(); 4430d163575Sopenharmony_ci if (group->netif_list == NULL) { 4440d163575Sopenharmony_ci#else 4450d163575Sopenharmony_ci if (netif_list == NULL) { 4460d163575Sopenharmony_ci#endif 4470d163575Sopenharmony_ci ret = snprintf_s(ifconfig_cmd->cb_print_buf, PRINT_BUF_LEN - ifconfig_cmd->print_len, 4480d163575Sopenharmony_ci ((PRINT_BUF_LEN - ifconfig_cmd->print_len) - 1), "Device not init\n"); 4490d163575Sopenharmony_ci if ((ret > 0) && ((unsigned int)ret < (PRINT_BUF_LEN - ifconfig_cmd->print_len))) { 4500d163575Sopenharmony_ci ifconfig_cmd->print_len += (unsigned int)ret; 4510d163575Sopenharmony_ci } 4520d163575Sopenharmony_ci sys_sem_signal(&ifconfig_cmd->cb_completed); 4530d163575Sopenharmony_ci return; 4540d163575Sopenharmony_ci } 4550d163575Sopenharmony_ci 4560d163575Sopenharmony_ci if (ifconfig_cmd->iface[0] == '\0') { 4570d163575Sopenharmony_ci /* display all netif */ 4580d163575Sopenharmony_ci#ifdef LOSCFG_NET_CONTAINER 4590d163575Sopenharmony_ci for (netif = group->netif_list; netif != NULL; netif = netif->next) { 4600d163575Sopenharmony_ci#else 4610d163575Sopenharmony_ci for (netif = netif_list; netif != NULL; netif = netif->next) { 4620d163575Sopenharmony_ci#endif 4630d163575Sopenharmony_ci ret = print_netif(netif, ifconfig_cmd->cb_print_buf + ifconfig_cmd->print_len, 4640d163575Sopenharmony_ci PRINT_BUF_LEN - ifconfig_cmd->print_len); 4650d163575Sopenharmony_ci ifconfig_cmd->print_len += (unsigned int)ret; 4660d163575Sopenharmony_ci } 4670d163575Sopenharmony_ci } else { 4680d163575Sopenharmony_ci netif = netif_find(ifconfig_cmd->iface); 4690d163575Sopenharmony_ci if (netif == NULL) { 4700d163575Sopenharmony_ci ret = snprintf_s(ifconfig_cmd->cb_print_buf + ifconfig_cmd->print_len, 4710d163575Sopenharmony_ci (PRINT_BUF_LEN - ifconfig_cmd->print_len), 4720d163575Sopenharmony_ci ((PRINT_BUF_LEN - ifconfig_cmd->print_len) - 1), "Device not found\n"); 4730d163575Sopenharmony_ci if ((ret > 0) && ((unsigned int)ret < (PRINT_BUF_LEN - ifconfig_cmd->print_len))) { 4740d163575Sopenharmony_ci ifconfig_cmd->print_len += (unsigned int)ret; 4750d163575Sopenharmony_ci } 4760d163575Sopenharmony_ci 4770d163575Sopenharmony_ci sys_sem_signal(&ifconfig_cmd->cb_completed); 4780d163575Sopenharmony_ci return; 4790d163575Sopenharmony_ci } 4800d163575Sopenharmony_ci 4810d163575Sopenharmony_ci ret = print_netif(netif, ifconfig_cmd->cb_print_buf + ifconfig_cmd->print_len, 4820d163575Sopenharmony_ci PRINT_BUF_LEN - ifconfig_cmd->print_len); 4830d163575Sopenharmony_ci ifconfig_cmd->print_len += (unsigned int)ret; 4840d163575Sopenharmony_ci } 4850d163575Sopenharmony_ci sys_sem_signal(&ifconfig_cmd->cb_completed); 4860d163575Sopenharmony_ci} 4870d163575Sopenharmony_ci 4880d163575Sopenharmony_ci#ifndef LWIP_TESTBED 4890d163575Sopenharmony_ciLWIP_STATIC 4900d163575Sopenharmony_ci#endif 4910d163575Sopenharmony_civoid lwip_ifconfig_internal(void *arg) 4920d163575Sopenharmony_ci{ 4930d163575Sopenharmony_ci struct ifconfig_option *ifconfig_cmd = NULL; 4940d163575Sopenharmony_ci struct netif *netif = NULL; 4950d163575Sopenharmony_ci ip_addr_t ip_addr; 4960d163575Sopenharmony_ci ip_addr_t netmask; 4970d163575Sopenharmony_ci ip_addr_t gw; 4980d163575Sopenharmony_ci unsigned short mtu; 4990d163575Sopenharmony_ci struct netif *loc_netif = NULL; 5000d163575Sopenharmony_ci int ret; 5010d163575Sopenharmony_ci s8_t idx; 5020d163575Sopenharmony_ci err_t err; 5030d163575Sopenharmony_ci#ifdef LOSCFG_NET_CONTAINER 5040d163575Sopenharmony_ci struct net_group *group = get_curr_process_net_group(); 5050d163575Sopenharmony_ci#endif 5060d163575Sopenharmony_ci ifconfig_cmd = (struct ifconfig_option *)arg; 5070d163575Sopenharmony_ci netif = netif_find(ifconfig_cmd->iface); 5080d163575Sopenharmony_ci if (netif == NULL) { 5090d163575Sopenharmony_ci ERR_IFCONFIG_STRING_PUT(ret, "Device not found\n"); 5100d163575Sopenharmony_ci goto out; 5110d163575Sopenharmony_ci } 5120d163575Sopenharmony_ci 5130d163575Sopenharmony_ci if (ifconfig_cmd->option & IFCONFIG_OPTION_SET_UP) { 5140d163575Sopenharmony_ci (void)netif_set_up(netif); 5150d163575Sopenharmony_ci goto out; 5160d163575Sopenharmony_ci } else if (ifconfig_cmd->option & IFCONFIG_OPTION_SET_DOWN) { 5170d163575Sopenharmony_ci (void)netif_set_down(netif); 5180d163575Sopenharmony_ci goto out; 5190d163575Sopenharmony_ci } 5200d163575Sopenharmony_ci 5210d163575Sopenharmony_ci if ((ifconfig_cmd->option & IFCONFIG_OPTION_SET_IP) || 5220d163575Sopenharmony_ci (ifconfig_cmd->option & IFCONFIG_OPTION_SET_NETMASK) || 5230d163575Sopenharmony_ci (ifconfig_cmd->option & IFCONFIG_OPTION_SET_HW)) { 5240d163575Sopenharmony_ci (void)netif_set_down(netif); 5250d163575Sopenharmony_ci } 5260d163575Sopenharmony_ci 5270d163575Sopenharmony_ci if (ifconfig_cmd->option & IFCONFIG_OPTION_SET_IP) { 5280d163575Sopenharmony_ci ip_addr_set_val(&ip_addr, &(ifconfig_cmd->ip_addr)); 5290d163575Sopenharmony_ci if (IP_IS_V4_VAL(ifconfig_cmd->ip_addr)) { 5300d163575Sopenharmony_ci /* check the address is not multicast/broadcast/0/loopback */ 5310d163575Sopenharmony_ci if (ip_addr_ismulticast_val(&ip_addr) || ip_addr_isbroadcast_val(&ip_addr, netif) || 5320d163575Sopenharmony_ci ip_addr_isany(&ip_addr) || ip_addr_isloopback(&ip_addr)) { 5330d163575Sopenharmony_ci ERR_IFCONFIG_STRING_PUT(ret, "Don't set ip as a multicast/broadcast/0/loopback address!\n"); 5340d163575Sopenharmony_ci goto out; 5350d163575Sopenharmony_ci } 5360d163575Sopenharmony_ci 5370d163575Sopenharmony_ci /* reset gateway if new and previous ipaddr not in same net */ 5380d163575Sopenharmony_ci if (!ip_addr_netcmp_val(&ip_addr, &netif->ip_addr, ip_2_ip4(&netif->netmask))) { 5390d163575Sopenharmony_ci ip_addr_set_zero(&netif->gw); 5400d163575Sopenharmony_ci#ifdef LOSCFG_NET_CONTAINER 5410d163575Sopenharmony_ci if (netif == group->netif_default) { 5420d163575Sopenharmony_ci (void)netif_set_default(NULL, group); 5430d163575Sopenharmony_ci#else 5440d163575Sopenharmony_ci if (netif == netif_default) { 5450d163575Sopenharmony_ci (void)netif_set_default(NULL); 5460d163575Sopenharmony_ci#endif 5470d163575Sopenharmony_ci } 5480d163575Sopenharmony_ci } 5490d163575Sopenharmony_ci 5500d163575Sopenharmony_ci /* lwip disallow two netif sit in same net at the same time */ 5510d163575Sopenharmony_ci#ifdef LOSCFG_NET_CONTAINER 5520d163575Sopenharmony_ci loc_netif = group->netif_list; 5530d163575Sopenharmony_ci#else 5540d163575Sopenharmony_ci loc_netif = netif_list; 5550d163575Sopenharmony_ci#endif 5560d163575Sopenharmony_ci while (loc_netif != NULL) { 5570d163575Sopenharmony_ci if (loc_netif == netif) { 5580d163575Sopenharmony_ci loc_netif = loc_netif->next; 5590d163575Sopenharmony_ci continue; 5600d163575Sopenharmony_ci } 5610d163575Sopenharmony_ci if (IP_IS_V4_VAL(ifconfig_cmd->ip_addr) && ip_addr_cmp(&netif->netmask, &loc_netif->netmask) && 5620d163575Sopenharmony_ci ip_addr_netcmp_val(&loc_netif->ip_addr, &ip_addr, ip_2_ip4(&netif->netmask))) { 5630d163575Sopenharmony_ci ERR_IFCONFIG_STRING_PUT(ret, "Duplicate network!\n"); 5640d163575Sopenharmony_ci goto out; 5650d163575Sopenharmony_ci } 5660d163575Sopenharmony_ci loc_netif = loc_netif->next; 5670d163575Sopenharmony_ci } 5680d163575Sopenharmony_ci 5690d163575Sopenharmony_ci#if LWIP_DHCP 5700d163575Sopenharmony_ci if (netif_dhcp_data(netif) && netif_dhcp_data(netif)->state != DHCP_STATE_OFF) { 5710d163575Sopenharmony_ci (void)netif_dhcp_off(netif); 5720d163575Sopenharmony_ci } 5730d163575Sopenharmony_ci#endif 5740d163575Sopenharmony_ci netif_set_ipaddr(netif, ip_2_ip4(&ip_addr)); 5750d163575Sopenharmony_ci } else if (IP_IS_V6_VAL(ifconfig_cmd->ip_addr)) { 5760d163575Sopenharmony_ci idx = -1; 5770d163575Sopenharmony_ci err = netif_add_ip6_address(netif, ip_2_ip6(&ip_addr), &idx); 5780d163575Sopenharmony_ci if (err != ERR_OK || idx == -1) { 5790d163575Sopenharmony_ci ERR_IFCONFIG_STRING_PUT(ret, "The IPv6 has reached the Global address limit, " 5800d163575Sopenharmony_ci "you should delete one address before add!\n"); 5810d163575Sopenharmony_ci goto out; 5820d163575Sopenharmony_ci } 5830d163575Sopenharmony_ci } 5840d163575Sopenharmony_ci } 5850d163575Sopenharmony_ci 5860d163575Sopenharmony_ci if (ifconfig_cmd->option & IFCONFIG_OPTION_DEL_IP) { 5870d163575Sopenharmony_ci (void)netif_do_rmv_ipv6_addr(netif, &ifconfig_cmd->ip_addr); 5880d163575Sopenharmony_ci } 5890d163575Sopenharmony_ci 5900d163575Sopenharmony_ci if (ifconfig_cmd->option & IFCONFIG_OPTION_SET_NETMASK) { 5910d163575Sopenharmony_ci ip_addr_set_val(&netmask, &(ifconfig_cmd->netmask)); 5920d163575Sopenharmony_ci /* check data valid */ 5930d163575Sopenharmony_ci if (!ip_addr_netmask_valid(ip_2_ip4(&netmask))) { 5940d163575Sopenharmony_ci ERR_IFCONFIG_STRING_PUT(ret, "ifconfig: netmask is invalid!\n"); 5950d163575Sopenharmony_ci goto out; 5960d163575Sopenharmony_ci } 5970d163575Sopenharmony_ci 5980d163575Sopenharmony_ci#if LWIP_DHCP 5990d163575Sopenharmony_ci if (netif_dhcp_data(netif) && netif_dhcp_data(netif)->state != DHCP_STATE_OFF) { 6000d163575Sopenharmony_ci (void)netif_dhcp_off(netif); 6010d163575Sopenharmony_ci } 6020d163575Sopenharmony_ci#endif 6030d163575Sopenharmony_ci if (netif_ip4_netmask(netif)->addr != ip_2_ip4(&netmask)->addr) { 6040d163575Sopenharmony_ci /* lwip disallow two netif sit in same net at the same time */ 6050d163575Sopenharmony_ci#ifdef LOSCFG_NET_CONTAINER 6060d163575Sopenharmony_ci loc_netif = group->netif_list; 6070d163575Sopenharmony_ci#else 6080d163575Sopenharmony_ci loc_netif = netif_list; 6090d163575Sopenharmony_ci#endif 6100d163575Sopenharmony_ci while (loc_netif != NULL) { 6110d163575Sopenharmony_ci if (loc_netif == netif) { 6120d163575Sopenharmony_ci loc_netif = loc_netif->next; 6130d163575Sopenharmony_ci continue; 6140d163575Sopenharmony_ci } 6150d163575Sopenharmony_ci if (ip_addr_cmp(&loc_netif->netmask, &netmask) && 6160d163575Sopenharmony_ci ip_addr_netcmp(&loc_netif->ip_addr, &netif->ip_addr, ip_2_ip4(&netmask))) { 6170d163575Sopenharmony_ci ERR_IFCONFIG_STRING_PUT(ret, "Duplicate network!\n"); 6180d163575Sopenharmony_ci goto out; 6190d163575Sopenharmony_ci } 6200d163575Sopenharmony_ci loc_netif = loc_netif->next; 6210d163575Sopenharmony_ci } 6220d163575Sopenharmony_ci netif_set_netmask(netif, ip_2_ip4(&netmask)); 6230d163575Sopenharmony_ci /* check if gateway still reachable */ 6240d163575Sopenharmony_ci if (!ip_addr_netcmp(&netif->gw, &netif->ip_addr, ip_2_ip4(&netmask))) { 6250d163575Sopenharmony_ci ip_addr_set_zero(&(netif->gw)); 6260d163575Sopenharmony_ci#ifdef LOSCFG_NET_CONTAINER 6270d163575Sopenharmony_ci if (netif == group->netif_default) { 6280d163575Sopenharmony_ci (void)netif_set_default(NULL, group); 6290d163575Sopenharmony_ci#else 6300d163575Sopenharmony_ci if (netif == netif_default) { 6310d163575Sopenharmony_ci (void)netif_set_default(NULL); 6320d163575Sopenharmony_ci#endif 6330d163575Sopenharmony_ci } 6340d163575Sopenharmony_ci } 6350d163575Sopenharmony_ci } 6360d163575Sopenharmony_ci } 6370d163575Sopenharmony_ci 6380d163575Sopenharmony_ci if ((ifconfig_cmd->option & IFCONFIG_OPTION_SET_HW) && 6390d163575Sopenharmony_ci netif_set_hwaddr(netif, ifconfig_cmd->ethaddr, NETIF_MAX_HWADDR_LEN) != ERR_OK) { 6400d163575Sopenharmony_ci ERR_IFCONFIG_STRING_PUT(ret, "Failed to update the hwaddr of the device!\n"); 6410d163575Sopenharmony_ci (void)netif_set_up(netif); 6420d163575Sopenharmony_ci goto out; 6430d163575Sopenharmony_ci } 6440d163575Sopenharmony_ci 6450d163575Sopenharmony_ci if ((ifconfig_cmd->option & IFCONFIG_OPTION_SET_IP) || 6460d163575Sopenharmony_ci (ifconfig_cmd->option & IFCONFIG_OPTION_SET_NETMASK) || 6470d163575Sopenharmony_ci (ifconfig_cmd->option & IFCONFIG_OPTION_SET_HW)) { 6480d163575Sopenharmony_ci (void)netif_set_up(netif); 6490d163575Sopenharmony_ci } 6500d163575Sopenharmony_ci 6510d163575Sopenharmony_ci if (ifconfig_cmd->option & IFCONFIG_OPTION_SET_GW) { 6520d163575Sopenharmony_ci ip_addr_set_val(&gw, &ifconfig_cmd->gw); 6530d163575Sopenharmony_ci 6540d163575Sopenharmony_ci /* check the address multicast/0/loopback */ 6550d163575Sopenharmony_ci if (ip_addr_ismulticast_val(&gw) || ip_addr_isbroadcast_val(&gw, netif) || 6560d163575Sopenharmony_ci ip_addr_isany(&gw) || ip_addr_isloopback(&gw)) { 6570d163575Sopenharmony_ci ERR_IFCONFIG_STRING_PUT(ret, "Don't set gateway as a multicast/broadcast/0/loopback address!\n"); 6580d163575Sopenharmony_ci goto out; 6590d163575Sopenharmony_ci } 6600d163575Sopenharmony_ci 6610d163575Sopenharmony_ci /* check if reachable */ 6620d163575Sopenharmony_ci if (!ip_addr_netcmp_val(&gw, &netif->ip_addr, ip_2_ip4(&netif->netmask))) { 6630d163575Sopenharmony_ci ERR_IFCONFIG_STRING_PUT(ret, "The address is unreachable!\n"); 6640d163575Sopenharmony_ci goto out; 6650d163575Sopenharmony_ci } 6660d163575Sopenharmony_ci 6670d163575Sopenharmony_ci#ifdef LOSCFG_NET_CONTAINER 6680d163575Sopenharmony_ci if (group->netif_default != netif) { 6690d163575Sopenharmony_ci ip_addr_set_zero(&netif->gw); 6700d163575Sopenharmony_ci (void)netif_set_default(netif, group); 6710d163575Sopenharmony_ci#else 6720d163575Sopenharmony_ci if (netif_default != netif) { 6730d163575Sopenharmony_ci ip_addr_set_zero(&netif->gw); 6740d163575Sopenharmony_ci (void)netif_set_default(netif); 6750d163575Sopenharmony_ci#endif 6760d163575Sopenharmony_ci } 6770d163575Sopenharmony_ci 6780d163575Sopenharmony_ci#if LWIP_DHCP 6790d163575Sopenharmony_ci if (netif_dhcp_data(netif) && netif_dhcp_data(netif)->state != DHCP_STATE_OFF) { 6800d163575Sopenharmony_ci (void)netif_dhcp_off(netif); 6810d163575Sopenharmony_ci } 6820d163575Sopenharmony_ci#endif 6830d163575Sopenharmony_ci netif_set_gw(netif, ip_2_ip4(&gw)); 6840d163575Sopenharmony_ci } 6850d163575Sopenharmony_ci 6860d163575Sopenharmony_ci if (ifconfig_cmd->option & IFCONFIG_OPTION_SET_MTU) { 6870d163575Sopenharmony_ci mtu = ifconfig_cmd->mtu; 6880d163575Sopenharmony_ci if (netif_set_mtu(netif, mtu) != ERR_OK) { 6890d163575Sopenharmony_ci ERR_IFCONFIG_STRING_PUT(ret, "Invalid MTU\n"); 6900d163575Sopenharmony_ci } 6910d163575Sopenharmony_ci } 6920d163575Sopenharmony_ciout: 6930d163575Sopenharmony_ci sys_sem_signal(&ifconfig_cmd->cb_completed); 6940d163575Sopenharmony_ci} 6950d163575Sopenharmony_ci 6960d163575Sopenharmony_ci 6970d163575Sopenharmony_civoid lwip_printsize(size_t size) 6980d163575Sopenharmony_ci{ 6990d163575Sopenharmony_ci static const char *SIZES[] = {"B", "KB", "MB", "GB"}; 7000d163575Sopenharmony_ci size_t divis = 0; 7010d163575Sopenharmony_ci size_t rem = 0; 7020d163575Sopenharmony_ci 7030d163575Sopenharmony_ci while ((size >= 1024) && (divis < ((sizeof(SIZES) / sizeof(char *)) - 1))) { 7040d163575Sopenharmony_ci rem = (size % 1024); 7050d163575Sopenharmony_ci divis++; 7060d163575Sopenharmony_ci size /= 1024; 7070d163575Sopenharmony_ci } 7080d163575Sopenharmony_ci 7090d163575Sopenharmony_ci PRINTK("(%.1f %s) \r\n", (float)size + (float)rem / 1024.0, SIZES[divis]); 7100d163575Sopenharmony_ci} 7110d163575Sopenharmony_ci 7120d163575Sopenharmony_ciLWIP_STATIC void lwip_ifconfig_usage(const char *cmd) 7130d163575Sopenharmony_ci{ 7140d163575Sopenharmony_ci PRINTK("Usage:"\ 7150d163575Sopenharmony_ci "\n%s [-a] "\ 7160d163575Sopenharmony_ci "\n[interface]"\ 7170d163575Sopenharmony_ci "\n[interface ipaddr] <netmask mask> <gateway gw>"\ 7180d163575Sopenharmony_ci "\n[interface inet6 add|del ipaddr]"\ 7190d163575Sopenharmony_ci "\n[interface hw ether MAC]"\ 7200d163575Sopenharmony_ci "\n[interface mtu NN]"\ 7210d163575Sopenharmony_ci "\n[interface up|down]\n", 7220d163575Sopenharmony_ci cmd); 7230d163575Sopenharmony_ci} 7240d163575Sopenharmony_ci 7250d163575Sopenharmony_ciu32_t lwip_ifconfig(int argc, const char **argv) 7260d163575Sopenharmony_ci{ 7270d163575Sopenharmony_ci int i; 7280d163575Sopenharmony_ci static struct ifconfig_option ifconfig_cmd; 7290d163575Sopenharmony_ci err_t ret; 7300d163575Sopenharmony_ci 7310d163575Sopenharmony_ci#if LWIP_STATS 7320d163575Sopenharmony_ci u32_t stat_err_cnt; 7330d163575Sopenharmony_ci u32_t stat_drop_cnt; 7340d163575Sopenharmony_ci u32_t stat_rx_or_tx_cnt; 7350d163575Sopenharmony_ci u32_t stat_rx_or_tx_bytes; 7360d163575Sopenharmony_ci#endif 7370d163575Sopenharmony_ci 7380d163575Sopenharmony_ci#if LWIP_ARP 7390d163575Sopenharmony_ci u32_t retval; 7400d163575Sopenharmony_ci struct netif *netiftmp = NULL; 7410d163575Sopenharmony_ci#if LWIP_ENABLE_IP_CONFLICT_SIGNAL 7420d163575Sopenharmony_ci u32_t old_ip4addr; 7430d163575Sopenharmony_ci err_t err; 7440d163575Sopenharmony_ci extern sys_sem_t ip_conflict_detect; 7450d163575Sopenharmony_ci extern u32_t is_ip_conflict_signal; 7460d163575Sopenharmony_ci#endif /* LWIP_ENABLE_IP_CONFLICT_SIGNAL */ 7470d163575Sopenharmony_ci#endif /* LWIP_ARP */ 7480d163575Sopenharmony_ci#if LWIP_IPV6 7490d163575Sopenharmony_ci extern sys_sem_t dup_addr_detect; 7500d163575Sopenharmony_ci extern u32_t is_dup_detect_initialized; 7510d163575Sopenharmony_ci#endif 7520d163575Sopenharmony_ci if (!tcpip_init_finish) { 7530d163575Sopenharmony_ci PRINTK("%s: tcpip_init have not been called\n", __FUNCTION__); 7540d163575Sopenharmony_ci return 2; 7550d163575Sopenharmony_ci } 7560d163575Sopenharmony_ci /* To support "ifconfig -a" command 7570d163575Sopenharmony_ci RX packets:XXXX errors:X dropped:X overruns:X bytes:XXXX (Human readable format) 7580d163575Sopenharmony_ci TX packets:XXXX errors:X dropped:X overruns:X bytes:XXXX (Human readable format) 7590d163575Sopenharmony_ci 7600d163575Sopenharmony_ci Below is assumed for 'overrun' stat. 7610d163575Sopenharmony_ci Linux Kernel: 7620d163575Sopenharmony_ci RX: FIFO overrun 7630d163575Sopenharmony_ci Data structure: net_device->stats->rx_fifo_errors 7640d163575Sopenharmony_ci Flag which is marked when FIFO overrun: ENRSR_FO 7650d163575Sopenharmony_ci 7660d163575Sopenharmony_ci Function: ei_receive->ENRSR_FO 7670d163575Sopenharmony_ci 7680d163575Sopenharmony_ci TX: A "FIFO underrun" occurred during transmit. 7690d163575Sopenharmony_ci Data structure: net_device->stats->tx_fifo_errors 7700d163575Sopenharmony_ci Flag which is marked when FIFO underrun: ENTSR_FU 7710d163575Sopenharmony_ci 7720d163575Sopenharmony_ci Function: ei_tx_intr->ENTSR_FU 7730d163575Sopenharmony_ci 7740d163575Sopenharmony_ci LWIP: 7750d163575Sopenharmony_ci So in our case, 7760d163575Sopenharmony_ci while receiving a packet RX case, if the buffer is full (trypost - it is sys_mbox_trypost) 7770d163575Sopenharmony_ci the error will be returned, we can consider that an overflow has happened. 7780d163575Sopenharmony_ci So this can be RX overrun. 7790d163575Sopenharmony_ci 7800d163575Sopenharmony_ci But while transmitting a packet TX case, underrun cannot happen because it block on the 7810d163575Sopenharmony_ci message Q if it is full (NOT trypost - it is sys_mbox_post). So TX overrun is always 0. 7820d163575Sopenharmony_ci */ 7830d163575Sopenharmony_ci if (argc) { 7840d163575Sopenharmony_ci if (strcmp("-a", argv[0]) == 0) { 7850d163575Sopenharmony_ci#if LWIP_STATS 7860d163575Sopenharmony_ci stat_rx_or_tx_cnt = lwip_stats.ip.recv; 7870d163575Sopenharmony_ci stat_err_cnt = (u32_t)(lwip_stats.ip.ip_rx_err + 7880d163575Sopenharmony_ci lwip_stats.ip.lenerr + 7890d163575Sopenharmony_ci lwip_stats.ip.chkerr + 7900d163575Sopenharmony_ci lwip_stats.ip.opterr + 7910d163575Sopenharmony_ci lwip_stats.ip.proterr); 7920d163575Sopenharmony_ci stat_drop_cnt = (u32_t)(lwip_stats.ip.drop + lwip_stats.link.link_rx_drop); 7930d163575Sopenharmony_ci stat_rx_or_tx_bytes = lwip_stats.ip.ip_rx_bytes; 7940d163575Sopenharmony_ci 7950d163575Sopenharmony_ci PRINTK("%18s:%u\t errors:%u\t ip dropped:%u\t link dropped:%u\t overrun:%d\t bytes:%u ", 7960d163575Sopenharmony_ci "RX packets", 7970d163575Sopenharmony_ci stat_rx_or_tx_cnt, 7980d163575Sopenharmony_ci stat_err_cnt, 7990d163575Sopenharmony_ci stat_drop_cnt, 8000d163575Sopenharmony_ci lwip_stats.link.link_rx_drop, 8010d163575Sopenharmony_ci lwip_stats.ip.link_rx_overrun, 8020d163575Sopenharmony_ci stat_rx_or_tx_bytes); 8030d163575Sopenharmony_ci 8040d163575Sopenharmony_ci /* Print in Human readable format of the incoming bytes */ 8050d163575Sopenharmony_ci lwip_printsize(lwip_stats.ip.ip_rx_bytes); 8060d163575Sopenharmony_ci#if IP6_STATS 8070d163575Sopenharmony_ci stat_rx_or_tx_cnt = lwip_stats.ip6.recv; 8080d163575Sopenharmony_ci stat_err_cnt = (u32_t)(lwip_stats.ip6.ip_rx_err + 8090d163575Sopenharmony_ci lwip_stats.ip6.lenerr + 8100d163575Sopenharmony_ci lwip_stats.ip6.chkerr + 8110d163575Sopenharmony_ci lwip_stats.ip6.opterr + 8120d163575Sopenharmony_ci lwip_stats.ip6.proterr); 8130d163575Sopenharmony_ci stat_drop_cnt = lwip_stats.ip6.drop; 8140d163575Sopenharmony_ci stat_rx_or_tx_bytes = lwip_stats.ip6.ip_rx_bytes; 8150d163575Sopenharmony_ci 8160d163575Sopenharmony_ci PRINTK("%18s:%u\t errors:%u\t dropped:%u\t overrun:%d\t bytes:%u ", 8170d163575Sopenharmony_ci "RX packets(ip6)", 8180d163575Sopenharmony_ci stat_rx_or_tx_cnt, 8190d163575Sopenharmony_ci stat_err_cnt, 8200d163575Sopenharmony_ci stat_drop_cnt, 8210d163575Sopenharmony_ci lwip_stats.ip.link_rx_overrun, 8220d163575Sopenharmony_ci stat_rx_or_tx_bytes); 8230d163575Sopenharmony_ci 8240d163575Sopenharmony_ci /* Print in Human readable format of the incoming bytes */ 8250d163575Sopenharmony_ci lwip_printsize(lwip_stats.ip6.ip_rx_bytes); 8260d163575Sopenharmony_ci#endif 8270d163575Sopenharmony_ci stat_rx_or_tx_cnt = (u32_t)(lwip_stats.ip.fw + lwip_stats.ip.xmit); 8280d163575Sopenharmony_ci stat_err_cnt = (u32_t)(lwip_stats.ip.rterr + lwip_stats.ip.ip_tx_err); 8290d163575Sopenharmony_ci /* IP layer drop stat param is not maintained, failure at IP is considered in 'errors' stat */ 8300d163575Sopenharmony_ci stat_drop_cnt = lwip_stats.link.link_tx_drop; 8310d163575Sopenharmony_ci stat_rx_or_tx_bytes = lwip_stats.ip.ip_tx_bytes; 8320d163575Sopenharmony_ci 8330d163575Sopenharmony_ci PRINTK("%18s:%u\t errors:%u\t link dropped:%u\t overrun:0\t bytes:%u", 8340d163575Sopenharmony_ci "TX packets", 8350d163575Sopenharmony_ci stat_rx_or_tx_cnt, 8360d163575Sopenharmony_ci stat_err_cnt, 8370d163575Sopenharmony_ci stat_drop_cnt, 8380d163575Sopenharmony_ci stat_rx_or_tx_bytes); 8390d163575Sopenharmony_ci 8400d163575Sopenharmony_ci /* Print in Human readable format of the outgoing bytes */ 8410d163575Sopenharmony_ci lwip_printsize(lwip_stats.ip.ip_tx_bytes); 8420d163575Sopenharmony_ci 8430d163575Sopenharmony_ci stat_rx_or_tx_cnt = (u32_t)(lwip_stats.ip6.fw + lwip_stats.ip6.xmit); 8440d163575Sopenharmony_ci stat_err_cnt = (u32_t)(lwip_stats.ip6.rterr + lwip_stats.ip6.ip_tx_err); 8450d163575Sopenharmony_ci stat_rx_or_tx_bytes = lwip_stats.ip6.ip_tx_bytes; 8460d163575Sopenharmony_ci 8470d163575Sopenharmony_ci PRINTK("%18s:%u\t errors:%u\t overrun:0\t bytes:%u", 8480d163575Sopenharmony_ci "TX packets(ip6)", 8490d163575Sopenharmony_ci stat_rx_or_tx_cnt, 8500d163575Sopenharmony_ci stat_err_cnt, 8510d163575Sopenharmony_ci stat_rx_or_tx_bytes); 8520d163575Sopenharmony_ci 8530d163575Sopenharmony_ci /* Print in Human readable format of the outgoing bytes */ 8540d163575Sopenharmony_ci lwip_printsize(lwip_stats.ip6.ip_tx_bytes); 8550d163575Sopenharmony_ci#endif /* LWIP_STATS */ 8560d163575Sopenharmony_ci return 0; 8570d163575Sopenharmony_ci } 8580d163575Sopenharmony_ci } 8590d163575Sopenharmony_ci 8600d163575Sopenharmony_ci (void)memset_s(&ifconfig_cmd, sizeof(ifconfig_cmd), 0, sizeof(ifconfig_cmd)); 8610d163575Sopenharmony_ci if (sys_sem_new(&ifconfig_cmd.cb_completed, 0) != ERR_OK) { 8620d163575Sopenharmony_ci PRINTK("%s: sys_sem_new fail\n", __FUNCTION__); 8630d163575Sopenharmony_ci return 1; 8640d163575Sopenharmony_ci } 8650d163575Sopenharmony_ci 8660d163575Sopenharmony_ci i = 0; 8670d163575Sopenharmony_ci /* Get the interface */ 8680d163575Sopenharmony_ci if (argc > 0) { 8690d163575Sopenharmony_ci if (strlen(argv[i]) < IFNAMSIZ) { 8700d163575Sopenharmony_ci if (strncpy_s(ifconfig_cmd.iface, IFNAMSIZ, argv[i], (strlen(argv[i]))) != EOK) { 8710d163575Sopenharmony_ci sys_sem_free(&ifconfig_cmd.cb_completed); 8720d163575Sopenharmony_ci PRINTK("ifconfig : strncpy_s error\n"); 8730d163575Sopenharmony_ci return 1; 8740d163575Sopenharmony_ci } 8750d163575Sopenharmony_ci ifconfig_cmd.iface[IFNAMSIZ - 1] = '\0'; 8760d163575Sopenharmony_ci } else { 8770d163575Sopenharmony_ci sys_sem_free(&ifconfig_cmd.cb_completed); 8780d163575Sopenharmony_ci PRINTK("ifconfig : interface name is too big\n"); 8790d163575Sopenharmony_ci return 1; 8800d163575Sopenharmony_ci } 8810d163575Sopenharmony_ci i++; 8820d163575Sopenharmony_ci argc--; 8830d163575Sopenharmony_ci if (argc == 0) { 8840d163575Sopenharmony_ci /* no more arguments, show the interface state. */ 8850d163575Sopenharmony_ci ret = tcpip_callback(lwip_ifconfig_show_internal, &ifconfig_cmd); 8860d163575Sopenharmony_ci if (ret != ERR_OK) { 8870d163575Sopenharmony_ci sys_sem_free(&ifconfig_cmd.cb_completed); 8880d163575Sopenharmony_ci PRINTK("ifconfig : internal error, l:%d err:%d\n", __LINE__, ret); 8890d163575Sopenharmony_ci return 1; 8900d163575Sopenharmony_ci } 8910d163575Sopenharmony_ci (void)sys_arch_sem_wait(&ifconfig_cmd.cb_completed, 0); 8920d163575Sopenharmony_ci sys_sem_free(&ifconfig_cmd.cb_completed); 8930d163575Sopenharmony_ci ifconfig_cmd.cb_print_buf[PRINT_BUF_LEN - 1] = '\0'; 8940d163575Sopenharmony_ci PRINTK("%s", ifconfig_cmd.cb_print_buf); 8950d163575Sopenharmony_ci return 0; 8960d163575Sopenharmony_ci } 8970d163575Sopenharmony_ci } else { 8980d163575Sopenharmony_ci /* no more arguments, show all the interface state. */ 8990d163575Sopenharmony_ci ret = tcpip_callback(lwip_ifconfig_show_internal, &ifconfig_cmd); 9000d163575Sopenharmony_ci if (ret != ERR_OK) { 9010d163575Sopenharmony_ci sys_sem_free(&ifconfig_cmd.cb_completed); 9020d163575Sopenharmony_ci PRINTK("ifconfig : internal error, l:%d err:%d\n", __LINE__, ret); 9030d163575Sopenharmony_ci return 1; 9040d163575Sopenharmony_ci } 9050d163575Sopenharmony_ci (void)sys_arch_sem_wait(&ifconfig_cmd.cb_completed, 0); 9060d163575Sopenharmony_ci sys_sem_free(&ifconfig_cmd.cb_completed); 9070d163575Sopenharmony_ci ifconfig_cmd.cb_print_buf[PRINT_BUF_LEN - 1] = '\0'; 9080d163575Sopenharmony_ci PRINTK("%s", ifconfig_cmd.cb_print_buf); 9090d163575Sopenharmony_ci 9100d163575Sopenharmony_ci return 0; 9110d163575Sopenharmony_ci } 9120d163575Sopenharmony_ci 9130d163575Sopenharmony_ci /* ifup/ifdown */ 9140d163575Sopenharmony_ci if (strcmp("up", argv[i]) == 0) { 9150d163575Sopenharmony_ci ifconfig_cmd.option |= IFCONFIG_OPTION_SET_UP; 9160d163575Sopenharmony_ci /* setup the interface, other arguments is ignored. */ 9170d163575Sopenharmony_ci ret = tcpip_callback(lwip_ifconfig_internal, &ifconfig_cmd); 9180d163575Sopenharmony_ci if (ret != ERR_OK) { 9190d163575Sopenharmony_ci sys_sem_free(&ifconfig_cmd.cb_completed); 9200d163575Sopenharmony_ci PRINTK("ifconfig : internal error, l:%d err:%d\n", __LINE__, ret); 9210d163575Sopenharmony_ci return 1; 9220d163575Sopenharmony_ci } 9230d163575Sopenharmony_ci (void)sys_arch_sem_wait(&ifconfig_cmd.cb_completed, 0); 9240d163575Sopenharmony_ci sys_sem_free(&ifconfig_cmd.cb_completed); 9250d163575Sopenharmony_ci ifconfig_cmd.cb_print_buf[PRINT_BUF_LEN - 1] = '\0'; 9260d163575Sopenharmony_ci PRINTK("%s", ifconfig_cmd.cb_print_buf); 9270d163575Sopenharmony_ci return 0; 9280d163575Sopenharmony_ci } else if (strcmp("down", argv[i]) == 0) { 9290d163575Sopenharmony_ci ifconfig_cmd.option |= IFCONFIG_OPTION_SET_DOWN; 9300d163575Sopenharmony_ci /* setdown the interface, other arguments is ignored. */ 9310d163575Sopenharmony_ci ret = tcpip_callback(lwip_ifconfig_internal, &ifconfig_cmd); 9320d163575Sopenharmony_ci if (ret != ERR_OK) { 9330d163575Sopenharmony_ci sys_sem_free(&ifconfig_cmd.cb_completed); 9340d163575Sopenharmony_ci PRINTK("ifconfig : internal error, l:%d err:%d\n", __LINE__, ret); 9350d163575Sopenharmony_ci return 1; 9360d163575Sopenharmony_ci } 9370d163575Sopenharmony_ci (void)sys_arch_sem_wait(&ifconfig_cmd.cb_completed, 0); 9380d163575Sopenharmony_ci sys_sem_free(&ifconfig_cmd.cb_completed); 9390d163575Sopenharmony_ci ifconfig_cmd.cb_print_buf[PRINT_BUF_LEN - 1] = '\0'; 9400d163575Sopenharmony_ci PRINTK("%s", ifconfig_cmd.cb_print_buf); 9410d163575Sopenharmony_ci return 0; 9420d163575Sopenharmony_ci } 9430d163575Sopenharmony_ci /* check if set the ip address. */ 9440d163575Sopenharmony_ci#if LWIP_ARP 9450d163575Sopenharmony_ci netiftmp = netifapi_netif_find_by_name(ifconfig_cmd.iface); 9460d163575Sopenharmony_ci if (netiftmp == NULL) { 9470d163575Sopenharmony_ci sys_sem_free(&ifconfig_cmd.cb_completed); 9480d163575Sopenharmony_ci PRINTK("ifconfig : Interface %s not found\n", ifconfig_cmd.iface); 9490d163575Sopenharmony_ci return 1; 9500d163575Sopenharmony_ci } 9510d163575Sopenharmony_ci#if LWIP_ENABLE_IP_CONFLICT_SIGNAL 9520d163575Sopenharmony_ci old_ip4addr = ipaddr_addr(ipaddr_ntoa(&netiftmp->ip_addr)); 9530d163575Sopenharmony_ci#endif /* LWIP_ENABLE_IP_CONFLICT_SIGNAL */ 9540d163575Sopenharmony_ci#endif /* LWIP_ARP */ 9550d163575Sopenharmony_ci if (!strcmp(argv[i], "inet") || ip4addr_aton(argv[i], ip_2_ip4(&ifconfig_cmd.ip_addr))) { 9560d163575Sopenharmony_ci if (!strcmp(argv[i], "inet")) { 9570d163575Sopenharmony_ci if (argc <= 1) { 9580d163575Sopenharmony_ci sys_sem_free(&ifconfig_cmd.cb_completed); 9590d163575Sopenharmony_ci goto ifconfig_error; 9600d163575Sopenharmony_ci } 9610d163575Sopenharmony_ci 9620d163575Sopenharmony_ci if (!ip4addr_aton(argv[i + 1], ip_2_ip4(&ifconfig_cmd.ip_addr))) { 9630d163575Sopenharmony_ci sys_sem_free(&ifconfig_cmd.cb_completed); 9640d163575Sopenharmony_ci PRINTK("ifconfig : Invalid IPv4 Address\n"); 9650d163575Sopenharmony_ci return 1; 9660d163575Sopenharmony_ci } 9670d163575Sopenharmony_ci argc--; 9680d163575Sopenharmony_ci i++; 9690d163575Sopenharmony_ci } 9700d163575Sopenharmony_ci IP_SET_TYPE_VAL((ifconfig_cmd.ip_addr), IPADDR_TYPE_V4); 9710d163575Sopenharmony_ci#if LWIP_ARP 9720d163575Sopenharmony_ci if (!ip_addr_cmp(&ifconfig_cmd.ip_addr, &netiftmp->ip_addr)) { 9730d163575Sopenharmony_ci ifconfig_cmd.option |= IFCONFIG_OPTION_SET_IP; 9740d163575Sopenharmony_ci } 9750d163575Sopenharmony_ci#else 9760d163575Sopenharmony_ci ifconfig_cmd.option |= IFCONFIG_OPTION_SET_IP; 9770d163575Sopenharmony_ci#endif /* LWIP_ARP */ 9780d163575Sopenharmony_ci argc--; 9790d163575Sopenharmony_ci i++; 9800d163575Sopenharmony_ci } else if (!strcmp(argv[i], "inet6")) { 9810d163575Sopenharmony_ci if (argc < 3) { 9820d163575Sopenharmony_ci sys_sem_free(&ifconfig_cmd.cb_completed); 9830d163575Sopenharmony_ci goto ifconfig_error; 9840d163575Sopenharmony_ci } 9850d163575Sopenharmony_ci if (strcmp(argv[i + 1], "add") && strcmp(argv[i + 1], "del")) { 9860d163575Sopenharmony_ci sys_sem_free(&ifconfig_cmd.cb_completed); 9870d163575Sopenharmony_ci goto ifconfig_error; 9880d163575Sopenharmony_ci } 9890d163575Sopenharmony_ci 9900d163575Sopenharmony_ci if (!ip6addr_aton(argv[i + 2], ip_2_ip6(&ifconfig_cmd.ip_addr))) { 9910d163575Sopenharmony_ci sys_sem_free(&ifconfig_cmd.cb_completed); 9920d163575Sopenharmony_ci PRINTK("ifconfig : Invalid IPv6 Address\n"); 9930d163575Sopenharmony_ci return 1; 9940d163575Sopenharmony_ci } 9950d163575Sopenharmony_ci 9960d163575Sopenharmony_ci IP_SET_TYPE_VAL((ifconfig_cmd.ip_addr), IPADDR_TYPE_V6); 9970d163575Sopenharmony_ci ifconfig_cmd.option |= (!strcmp(argv[i + 1], "add") ? IFCONFIG_OPTION_SET_IP : IFCONFIG_OPTION_DEL_IP); 9980d163575Sopenharmony_ci argc -= 3; 9990d163575Sopenharmony_ci i += 3; 10000d163575Sopenharmony_ci } 10010d163575Sopenharmony_ci 10020d163575Sopenharmony_ci if (ifconfig_cmd.option & IFCONFIG_OPTION_DEL_IP) { 10030d163575Sopenharmony_ci if (argc != 0) { 10040d163575Sopenharmony_ci sys_sem_free(&ifconfig_cmd.cb_completed); 10050d163575Sopenharmony_ci goto ifconfig_error; 10060d163575Sopenharmony_ci } 10070d163575Sopenharmony_ci } 10080d163575Sopenharmony_ci 10090d163575Sopenharmony_ci while (argc > 0) { 10100d163575Sopenharmony_ci if (strcmp("netmask", argv[i]) == 0 && (argc > 1) && (ipaddr_addr(argv[i + 1]) != IPADDR_NONE)) { 10110d163575Sopenharmony_ci /* if set netmask */ 10120d163575Sopenharmony_ci ip_addr_set_ip4_u32_val((ifconfig_cmd.netmask), ipaddr_addr(argv[i + 1])); 10130d163575Sopenharmony_ci ifconfig_cmd.option |= IFCONFIG_OPTION_SET_NETMASK; 10140d163575Sopenharmony_ci i += 2; 10150d163575Sopenharmony_ci argc -= 2; 10160d163575Sopenharmony_ci } else if (strcmp("gateway", argv[i]) == 0 && (argc > 1) && (ipaddr_addr(argv[i + 1]) != IPADDR_NONE)) { 10170d163575Sopenharmony_ci /* if set gateway */ 10180d163575Sopenharmony_ci ip_addr_set_ip4_u32_val((ifconfig_cmd.gw), ipaddr_addr(argv[i + 1])); 10190d163575Sopenharmony_ci ifconfig_cmd.option |= IFCONFIG_OPTION_SET_GW; 10200d163575Sopenharmony_ci i += 2; 10210d163575Sopenharmony_ci argc -= 2; 10220d163575Sopenharmony_ci } else if (strcmp("hw", argv[i]) == 0 && argc > 2 && strcmp("ether", argv[i + 1]) == 0) { 10230d163575Sopenharmony_ci /* if set HWaddr */ 10240d163575Sopenharmony_ci char *digit = NULL; 10250d163575Sopenharmony_ci u32_t macaddrlen = strlen(argv[i + 2]) + 1; 10260d163575Sopenharmony_ci char tmpStr[MAX_MACADDR_STRING_LENGTH]; 10270d163575Sopenharmony_ci char *tmpStr1 = NULL; 10280d163575Sopenharmony_ci char *saveptr = NULL; 10290d163575Sopenharmony_ci int j; 10300d163575Sopenharmony_ci 10310d163575Sopenharmony_ci if (macaddrlen != MAX_MACADDR_STRING_LENGTH) { 10320d163575Sopenharmony_ci sys_sem_free(&ifconfig_cmd.cb_completed); 10330d163575Sopenharmony_ci PRINTK("ifconfig : wrong MAC address format\n"); 10340d163575Sopenharmony_ci return 1; 10350d163575Sopenharmony_ci } 10360d163575Sopenharmony_ci 10370d163575Sopenharmony_ci if (strncpy_s(tmpStr, MAX_MACADDR_STRING_LENGTH, argv[i + 2], macaddrlen - 1) != 0) { 10380d163575Sopenharmony_ci sys_sem_free(&ifconfig_cmd.cb_completed); 10390d163575Sopenharmony_ci PRINTK("ifconfig : wrong MAC address\n"); 10400d163575Sopenharmony_ci return 1; 10410d163575Sopenharmony_ci } 10420d163575Sopenharmony_ci for (j = 0, tmpStr1 = tmpStr; j < 6; j++, tmpStr1 = NULL) { 10430d163575Sopenharmony_ci digit = strtok_r(tmpStr1, ":", &saveptr); 10440d163575Sopenharmony_ci if ((digit == NULL) || (strlen(digit) > 2)) { 10450d163575Sopenharmony_ci sys_sem_free(&ifconfig_cmd.cb_completed); 10460d163575Sopenharmony_ci PRINTK("ifconfig : wrong MAC address format\n"); 10470d163575Sopenharmony_ci return 1; 10480d163575Sopenharmony_ci } 10490d163575Sopenharmony_ci CONVERT_STRING_TO_HEX(digit, ifconfig_cmd.ethaddr[j]); 10500d163575Sopenharmony_ci } 10510d163575Sopenharmony_ci ifconfig_cmd.option |= IFCONFIG_OPTION_SET_HW; 10520d163575Sopenharmony_ci i += 3; 10530d163575Sopenharmony_ci argc -= 3; 10540d163575Sopenharmony_ci } else if (!strcmp("mtu", argv[i]) && (argc > 1)) { 10550d163575Sopenharmony_ci /* if set mtu */ 10560d163575Sopenharmony_ci if ((atoi(argv[i + 1]) < 0) || (atoi(argv[i + 1]) > 0xFFFF)) { 10570d163575Sopenharmony_ci sys_sem_free(&ifconfig_cmd.cb_completed); 10580d163575Sopenharmony_ci PRINTK("\nifconfig: Invalid argument for mtu\n"); 10590d163575Sopenharmony_ci goto ifconfig_error; 10600d163575Sopenharmony_ci } 10610d163575Sopenharmony_ci 10620d163575Sopenharmony_ci ifconfig_cmd.mtu = (u16_t)(atoi(argv[i + 1])); 10630d163575Sopenharmony_ci ifconfig_cmd.option |= IFCONFIG_OPTION_SET_MTU; 10640d163575Sopenharmony_ci i += 2; 10650d163575Sopenharmony_ci argc -= 2; 10660d163575Sopenharmony_ci } else { 10670d163575Sopenharmony_ci sys_sem_free(&ifconfig_cmd.cb_completed); 10680d163575Sopenharmony_ci goto ifconfig_error; 10690d163575Sopenharmony_ci } 10700d163575Sopenharmony_ci } 10710d163575Sopenharmony_ci 10720d163575Sopenharmony_ci#if LWIP_ARP && LWIP_ENABLE_IP_CONFLICT_SIGNAL 10730d163575Sopenharmony_ci if ((ifconfig_cmd.option & IFCONFIG_OPTION_SET_IP) && IP_IS_V4_VAL((ifconfig_cmd.ip_addr))) { 10740d163575Sopenharmony_ci /* Create the semaphore for ip conflict detection. */ 10750d163575Sopenharmony_ci if (sys_sem_new(&ip_conflict_detect, 0) != ERR_OK) { 10760d163575Sopenharmony_ci sys_sem_free(&ifconfig_cmd.cb_completed); 10770d163575Sopenharmony_ci PRINTK("ifconfig: internal error\n"); 10780d163575Sopenharmony_ci return 1; 10790d163575Sopenharmony_ci } 10800d163575Sopenharmony_ci is_ip_conflict_signal = 1; 10810d163575Sopenharmony_ci } 10820d163575Sopenharmony_ci#endif /* LWIP_ARP && LWIP_ENABLE_IP_CONFLICT_SIGNAL */ 10830d163575Sopenharmony_ci 10840d163575Sopenharmony_ci#if LWIP_IPV6 10850d163575Sopenharmony_ci if ((ifconfig_cmd.option & IFCONFIG_OPTION_SET_IP) && IP_IS_V6_VAL((ifconfig_cmd.ip_addr))) { 10860d163575Sopenharmony_ci /* Create the semaphore for duplicate address detection. */ 10870d163575Sopenharmony_ci if (sys_sem_new(&dup_addr_detect, 0) != ERR_OK) { 10880d163575Sopenharmony_ci sys_sem_free(&ifconfig_cmd.cb_completed); 10890d163575Sopenharmony_ci PRINTK("ifconfig: internal error\n"); 10900d163575Sopenharmony_ci return 1; 10910d163575Sopenharmony_ci } 10920d163575Sopenharmony_ci is_dup_detect_initialized = 1; 10930d163575Sopenharmony_ci } 10940d163575Sopenharmony_ci#endif /* LWIP_IPV6 */ 10950d163575Sopenharmony_ci 10960d163575Sopenharmony_ci ret = tcpip_callback(lwip_ifconfig_internal, &ifconfig_cmd); 10970d163575Sopenharmony_ci if (ret != ERR_OK) { 10980d163575Sopenharmony_ci sys_sem_free(&ifconfig_cmd.cb_completed); 10990d163575Sopenharmony_ci#if LWIP_ARP && LWIP_ENABLE_IP_CONFLICT_SIGNAL 11000d163575Sopenharmony_ci if ((ifconfig_cmd.option & IFCONFIG_OPTION_SET_IP) && IP_IS_V4_VAL((ifconfig_cmd.ip_addr))) { 11010d163575Sopenharmony_ci is_ip_conflict_signal = 0; 11020d163575Sopenharmony_ci sys_sem_free(&ip_conflict_detect); 11030d163575Sopenharmony_ci } 11040d163575Sopenharmony_ci#endif /* LWIP_ARP && LWIP_ENABLE_IP_CONFLICT_SIGNAL */ 11050d163575Sopenharmony_ci 11060d163575Sopenharmony_ci#if LWIP_IPV6 11070d163575Sopenharmony_ci if ((ifconfig_cmd.option & IFCONFIG_OPTION_SET_IP) && IP_IS_V6_VAL((ifconfig_cmd.ip_addr))) { 11080d163575Sopenharmony_ci is_dup_detect_initialized = 0; 11090d163575Sopenharmony_ci sys_sem_free(&dup_addr_detect); 11100d163575Sopenharmony_ci } 11110d163575Sopenharmony_ci#endif /* LWIP_IPV6 */ 11120d163575Sopenharmony_ci 11130d163575Sopenharmony_ci PRINTK("%s : tcpip_callback failed in line %d : errnu %d", __FUNCTION__, __LINE__, ret); 11140d163575Sopenharmony_ci return 1; 11150d163575Sopenharmony_ci } 11160d163575Sopenharmony_ci (void)sys_arch_sem_wait(&ifconfig_cmd.cb_completed, 0); 11170d163575Sopenharmony_ci ifconfig_cmd.cb_print_buf[PRINT_BUF_LEN - 1] = '\0'; 11180d163575Sopenharmony_ci PRINTK("%s", ifconfig_cmd.cb_print_buf); 11190d163575Sopenharmony_ci#if LWIP_ARP && LWIP_ENABLE_IP_CONFLICT_SIGNAL 11200d163575Sopenharmony_ci /* Pend 2 seconds for waiting the arp reply if the ip is already in use. */ 11210d163575Sopenharmony_ci if ((ifconfig_cmd.option & IFCONFIG_OPTION_SET_IP) && IP_IS_V4_VAL((ifconfig_cmd.ip_addr))) { 11220d163575Sopenharmony_ci err = (err_t)sys_arch_sem_wait(&ip_conflict_detect, DUP_ARP_DETECT_TIME); 11230d163575Sopenharmony_ci is_ip_conflict_signal = 0; 11240d163575Sopenharmony_ci sys_sem_free(&ip_conflict_detect); 11250d163575Sopenharmony_ci if (err < 0) { 11260d163575Sopenharmony_ci /* The result neither conflict nor timeout. */ 11270d163575Sopenharmony_ci PRINT_ERR("ifconfig: internal error\n"); 11280d163575Sopenharmony_ci sys_sem_free(&ifconfig_cmd.cb_completed); 11290d163575Sopenharmony_ci return 1; 11300d163575Sopenharmony_ci } else if (err < DUP_ARP_DETECT_TIME) { 11310d163575Sopenharmony_ci /* Duplicate use of new ip, restore it to the old one. */ 11320d163575Sopenharmony_ci PRINT_ERR("ifconfig: ip conflict!\n"); 11330d163575Sopenharmony_ci ip_addr_set_ip4_u32_val(ifconfig_cmd.ip_addr, old_ip4addr); 11340d163575Sopenharmony_ci ret = tcpip_callback(lwip_ifconfig_internal, &ifconfig_cmd); 11350d163575Sopenharmony_ci if (ret != ERR_OK) { 11360d163575Sopenharmony_ci sys_sem_free(&ifconfig_cmd.cb_completed); 11370d163575Sopenharmony_ci PRINTK("%s : tcpip_callback failed in line %d : errnu %d", __FUNCTION__, __LINE__, ret); 11380d163575Sopenharmony_ci return 1; 11390d163575Sopenharmony_ci } 11400d163575Sopenharmony_ci (void)sys_arch_sem_wait(&ifconfig_cmd.cb_completed, 0); 11410d163575Sopenharmony_ci sys_sem_free(&ifconfig_cmd.cb_completed); 11420d163575Sopenharmony_ci ifconfig_cmd.cb_print_buf[PRINT_BUF_LEN - 1] = '\0'; 11430d163575Sopenharmony_ci PRINTK("%s", ifconfig_cmd.cb_print_buf); 11440d163575Sopenharmony_ci return 1; 11450d163575Sopenharmony_ci } 11460d163575Sopenharmony_ci } 11470d163575Sopenharmony_ci#endif /* LWIP_ARP && LWIP_ENABLE_IP_CONFLICT_SIGNAL */ 11480d163575Sopenharmony_ci#if LWIP_IPV6 11490d163575Sopenharmony_ci if ((ifconfig_cmd.option & IFCONFIG_OPTION_SET_IP) && IP_IS_V6_VAL(ifconfig_cmd.ip_addr)) { 11500d163575Sopenharmony_ci /* Pend 2 seconds for waiting the arp reply if the ip is already in use. */ 11510d163575Sopenharmony_ci retval = sys_arch_sem_wait(&dup_addr_detect, DUP_ARP_DETECT_TIME); 11520d163575Sopenharmony_ci is_dup_detect_initialized = 0; 11530d163575Sopenharmony_ci sys_sem_free(&dup_addr_detect); 11540d163575Sopenharmony_ci if (retval == SYS_ARCH_ERROR) { 11550d163575Sopenharmony_ci sys_sem_free(&ifconfig_cmd.cb_completed); 11560d163575Sopenharmony_ci /* The result neither conflict nor timeout. */ 11570d163575Sopenharmony_ci PRINT_ERR("ifconfig: internal error\n"); 11580d163575Sopenharmony_ci return 1; 11590d163575Sopenharmony_ci } else if (retval < DUP_ARP_DETECT_TIME) { 11600d163575Sopenharmony_ci /* Duplicate use of new ip, restore it to the old one. */ 11610d163575Sopenharmony_ci struct netif *netif = NULL; 11620d163575Sopenharmony_ci PRINT_ERR("ifconfig: IP conflict!\n"); 11630d163575Sopenharmony_ci netif = netifapi_netif_find_by_name(ifconfig_cmd.iface); 11640d163575Sopenharmony_ci i = netif_get_ip6_addr_match(netif, &ifconfig_cmd.ip_addr.u_addr.ip6); 11650d163575Sopenharmony_ci if (i >= 0) { 11660d163575Sopenharmony_ci netif->ip6_addr_state[i] = IP6_ADDR_INVALID; 11670d163575Sopenharmony_ci } 11680d163575Sopenharmony_ci 11690d163575Sopenharmony_ci sys_sem_free(&ifconfig_cmd.cb_completed); 11700d163575Sopenharmony_ci ifconfig_cmd.cb_print_buf[PRINT_BUF_LEN - 1] = '\0'; 11710d163575Sopenharmony_ci PRINTK("%s", ifconfig_cmd.cb_print_buf); 11720d163575Sopenharmony_ci return 1; 11730d163575Sopenharmony_ci } 11740d163575Sopenharmony_ci } 11750d163575Sopenharmony_ci#endif /* LWIP_IPV6 */ 11760d163575Sopenharmony_ci sys_sem_free(&ifconfig_cmd.cb_completed); 11770d163575Sopenharmony_ci return 0; 11780d163575Sopenharmony_ciifconfig_error: 11790d163575Sopenharmony_ci lwip_ifconfig_usage("ifconfig"); 11800d163575Sopenharmony_ci return 1; 11810d163575Sopenharmony_ci} 11820d163575Sopenharmony_ci 11830d163575Sopenharmony_ci#ifdef LOSCFG_SHELL 11840d163575Sopenharmony_ciSHELLCMD_ENTRY(ifconfig_shellcmd, CMD_TYPE_EX, "ifconfig", XARGS, (CmdCallBackFunc)lwip_ifconfig); 11850d163575Sopenharmony_ci#endif /* LOSCFG_SHELL */ 11860d163575Sopenharmony_ci/* add arp entry to arp cache */ 11870d163575Sopenharmony_ci#define ARP_OPTION_ADD 1 11880d163575Sopenharmony_ci/* delete arp entry to arp cache */ 11890d163575Sopenharmony_ci#define ARP_OPTION_DEL 2 11900d163575Sopenharmony_ci/* print all arp entry in arp cache */ 11910d163575Sopenharmony_ci#define ARP_OPTION_SHOW 3 11920d163575Sopenharmony_ci 11930d163575Sopenharmony_cistruct arp_option { 11940d163575Sopenharmony_ci /* see the ARP_OPTION_ above */ 11950d163575Sopenharmony_ci int option; 11960d163575Sopenharmony_ci /* descriptive abbreviation of network interface */ 11970d163575Sopenharmony_ci char iface[IFNAMSIZ]; 11980d163575Sopenharmony_ci /* ip addr */ 11990d163575Sopenharmony_ci unsigned int ipaddr; 12000d163575Sopenharmony_ci /* hw addr */ 12010d163575Sopenharmony_ci unsigned char ethaddr[6]; 12020d163575Sopenharmony_ci /* when using telnet, print to the telnet socket will result in system */ 12030d163575Sopenharmony_ci /* deadlock.so don't do it. cache the data to print to a buf, and when */ 12040d163575Sopenharmony_ci /* callback returns, then print the data out to the telnet socket */ 12050d163575Sopenharmony_ci sys_sem_t cb_completed; 12060d163575Sopenharmony_ci char cb_print_buf[PRINT_BUF_LEN]; 12070d163575Sopenharmony_ci int print_buf_len; 12080d163575Sopenharmony_ci}; 12090d163575Sopenharmony_ci 12100d163575Sopenharmony_ci#ifndef LWIP_TESTBED 12110d163575Sopenharmony_ciLWIP_STATIC 12120d163575Sopenharmony_ci#endif 12130d163575Sopenharmony_civoid lwip_arp_show_internal(struct netif *netif, char *printf_buf, unsigned int buf_len) 12140d163575Sopenharmony_ci{ 12150d163575Sopenharmony_ci u8_t state, i; 12160d163575Sopenharmony_ci int ret; 12170d163575Sopenharmony_ci char *tmp = printf_buf; 12180d163575Sopenharmony_ci if (buf_len < 1) { 12190d163575Sopenharmony_ci return; 12200d163575Sopenharmony_ci } 12210d163575Sopenharmony_ci ret = snprintf_s(tmp, buf_len, (buf_len - 1), "%-24s%-24s%-12s%-12s\n", "Address", "HWaddress", "Iface", "Type"); 12220d163575Sopenharmony_ci if ((ret <= 0) || ((unsigned int)ret >= buf_len)) 12230d163575Sopenharmony_ci return; 12240d163575Sopenharmony_ci tmp += ret; 12250d163575Sopenharmony_ci buf_len -= (unsigned int)ret; 12260d163575Sopenharmony_ci 12270d163575Sopenharmony_ci if (netif != NULL) { 12280d163575Sopenharmony_ci for (i = 0; i < ARP_TABLE_SIZE; ++i) { 12290d163575Sopenharmony_ci state = arp_table[i].state; 12300d163575Sopenharmony_ci if (((state == ETHARP_STATE_STABLE) 12310d163575Sopenharmony_ci #if ETHARP_SUPPORT_STATIC_ENTRIES 12320d163575Sopenharmony_ci || (state == ETHARP_STATE_STATIC) 12330d163575Sopenharmony_ci#endif /* ETHARP_SUPPORT_STATIC_ENTRIES */ 12340d163575Sopenharmony_ci ) && arp_table[i].netif) { 12350d163575Sopenharmony_ci if (strcmp(netif_get_name(netif), netif_get_name(arp_table[i].netif)) != 0) { 12360d163575Sopenharmony_ci continue; 12370d163575Sopenharmony_ci } 12380d163575Sopenharmony_ci 12390d163575Sopenharmony_ci ret = snprintf_s(tmp, buf_len, (buf_len - 1), "%-24s%02X:%02X:%02X:%02X:%02X:%02X %s %s\n", 12400d163575Sopenharmony_ci ip4addr_ntoa(&arp_table[i].ipaddr), 12410d163575Sopenharmony_ci arp_table[i].ethaddr.addr[0], arp_table[i].ethaddr.addr[1], 12420d163575Sopenharmony_ci arp_table[i].ethaddr.addr[2], arp_table[i].ethaddr.addr[3], 12430d163575Sopenharmony_ci arp_table[i].ethaddr.addr[4], arp_table[i].ethaddr.addr[5], 12440d163575Sopenharmony_ci netif_get_name(netif), 12450d163575Sopenharmony_ci#if ETHARP_SUPPORT_STATIC_ENTRIES 12460d163575Sopenharmony_ci ((state == ETHARP_STATE_STATIC) ? "static" : "dynamic") 12470d163575Sopenharmony_ci#else 12480d163575Sopenharmony_ci "dynamic" 12490d163575Sopenharmony_ci#endif /* ETHARP_SUPPORT_STATIC_ENTRIES */ 12500d163575Sopenharmony_ci ); 12510d163575Sopenharmony_ci if ((ret <= 0) || ((unsigned int)ret >= buf_len)) 12520d163575Sopenharmony_ci return; 12530d163575Sopenharmony_ci tmp += ret; 12540d163575Sopenharmony_ci buf_len -= (unsigned int)ret; 12550d163575Sopenharmony_ci } 12560d163575Sopenharmony_ci } 12570d163575Sopenharmony_ci } else { 12580d163575Sopenharmony_ci for (i = 0; i < ARP_TABLE_SIZE; ++i) { 12590d163575Sopenharmony_ci state = arp_table[i].state; 12600d163575Sopenharmony_ci if (((state == ETHARP_STATE_STABLE) 12610d163575Sopenharmony_ci #if ETHARP_SUPPORT_STATIC_ENTRIES 12620d163575Sopenharmony_ci || (state == ETHARP_STATE_STATIC) 12630d163575Sopenharmony_ci#endif /* ETHARP_SUPPORT_STATIC_ENTRIES */ 12640d163575Sopenharmony_ci ) && arp_table[i].netif) { 12650d163575Sopenharmony_ci ret = snprintf_s(tmp, buf_len, (buf_len - 1), "%-24s%02X:%02X:%02X:%02X:%02X:%02X %s %s\n", 12660d163575Sopenharmony_ci ip4addr_ntoa(&arp_table[i].ipaddr), 12670d163575Sopenharmony_ci arp_table[i].ethaddr.addr[0], arp_table[i].ethaddr.addr[1], 12680d163575Sopenharmony_ci arp_table[i].ethaddr.addr[2], arp_table[i].ethaddr.addr[3], 12690d163575Sopenharmony_ci arp_table[i].ethaddr.addr[4], arp_table[i].ethaddr.addr[5], 12700d163575Sopenharmony_ci netif_get_name(arp_table[i].netif), 12710d163575Sopenharmony_ci#if ETHARP_SUPPORT_STATIC_ENTRIES 12720d163575Sopenharmony_ci ((state == ETHARP_STATE_STATIC) ? "static" : "dynamic") 12730d163575Sopenharmony_ci#else 12740d163575Sopenharmony_ci "dynamic" 12750d163575Sopenharmony_ci#endif /* ETHARP_SUPPORT_STATIC_ENTRIES */ 12760d163575Sopenharmony_ci ); 12770d163575Sopenharmony_ci if ((ret <= 0) || ((unsigned int)ret >= buf_len)) 12780d163575Sopenharmony_ci return; 12790d163575Sopenharmony_ci tmp += ret; 12800d163575Sopenharmony_ci buf_len -= (unsigned int)ret; 12810d163575Sopenharmony_ci } 12820d163575Sopenharmony_ci } 12830d163575Sopenharmony_ci } 12840d163575Sopenharmony_ci} 12850d163575Sopenharmony_ci 12860d163575Sopenharmony_ci#ifndef LWIP_TESTBED 12870d163575Sopenharmony_ciLWIP_STATIC 12880d163575Sopenharmony_ci#endif 12890d163575Sopenharmony_civoid lwip_arp_internal(void *arg) 12900d163575Sopenharmony_ci{ 12910d163575Sopenharmony_ci#if LWIP_IPV4 12920d163575Sopenharmony_ci struct arp_option *arp_cmd = (struct arp_option *)arg; 12930d163575Sopenharmony_ci struct netif *netif = NULL; 12940d163575Sopenharmony_ci struct eth_addr ethaddr; 12950d163575Sopenharmony_ci ip4_addr_t ipaddr; 12960d163575Sopenharmony_ci err_t ret = 0; 12970d163575Sopenharmony_ci int type = 0; 12980d163575Sopenharmony_ci#ifdef LOSCFG_NET_CONTAINER 12990d163575Sopenharmony_ci struct net_group *group = get_curr_process_net_group(); 13000d163575Sopenharmony_ci#endif 13010d163575Sopenharmony_ci if (arp_cmd->iface[0] == 'd' && arp_cmd->iface[1] == 'e') { 13020d163575Sopenharmony_ci netif = NULL; 13030d163575Sopenharmony_ci } else { 13040d163575Sopenharmony_ci /* find the specified netif by it's name */ 13050d163575Sopenharmony_ci netif = netif_find(arp_cmd->iface); 13060d163575Sopenharmony_ci if (netif == NULL) { 13070d163575Sopenharmony_ci (void)snprintf_s(arp_cmd->cb_print_buf, PRINT_BUF_LEN, (PRINT_BUF_LEN - 1), "No such device\n"); 13080d163575Sopenharmony_ci goto out; 13090d163575Sopenharmony_ci } 13100d163575Sopenharmony_ci } 13110d163575Sopenharmony_ci 13120d163575Sopenharmony_ci type = arp_cmd->option; 13130d163575Sopenharmony_ci switch (type) { 13140d163575Sopenharmony_ci case ARP_OPTION_SHOW: 13150d163575Sopenharmony_ci if (netif != NULL) { 13160d163575Sopenharmony_ci lwip_arp_show_internal(netif, arp_cmd->cb_print_buf, PRINT_BUF_LEN); 13170d163575Sopenharmony_ci } else { 13180d163575Sopenharmony_ci lwip_arp_show_internal(NULL, arp_cmd->cb_print_buf, PRINT_BUF_LEN); 13190d163575Sopenharmony_ci } 13200d163575Sopenharmony_ci break; 13210d163575Sopenharmony_ci 13220d163575Sopenharmony_ci case ARP_OPTION_ADD: 13230d163575Sopenharmony_ci#if ETHARP_SUPPORT_STATIC_ENTRIES 13240d163575Sopenharmony_ci ipaddr.addr = arp_cmd->ipaddr; 13250d163575Sopenharmony_ci (void)memcpy_s(ethaddr.addr, sizeof(ethaddr.addr), arp_cmd->ethaddr, 6); 13260d163575Sopenharmony_ci if (netif != NULL) { 13270d163575Sopenharmony_ci if (ip4_addr_netcmp(&ipaddr, ip_2_ip4(&(netif->ip_addr)), ip_2_ip4(&(netif->netmask)))) { 13280d163575Sopenharmony_ci ret = etharp_update_arp_entry(netif, &ipaddr, ðaddr, 13290d163575Sopenharmony_ci ETHARP_FLAG_TRY_HARD | ETHARP_FLAG_STATIC_ENTRY); 13300d163575Sopenharmony_ci } else { 13310d163575Sopenharmony_ci ret = ERR_RTE; 13320d163575Sopenharmony_ci } 13330d163575Sopenharmony_ci } else { 13340d163575Sopenharmony_ci ret = etharp_add_static_entry(&ipaddr, ðaddr); 13350d163575Sopenharmony_ci } 13360d163575Sopenharmony_ci#else 13370d163575Sopenharmony_ci ret = ERR_ARG; 13380d163575Sopenharmony_ci#endif /* ETHARP_SUPPORT_STATIC_ENTRIES */ 13390d163575Sopenharmony_ci break; 13400d163575Sopenharmony_ci 13410d163575Sopenharmony_ci case ARP_OPTION_DEL: 13420d163575Sopenharmony_ci ipaddr.addr = arp_cmd->ipaddr; 13430d163575Sopenharmony_ci (void)memcpy_s(ethaddr.addr, sizeof(ethaddr.addr), arp_cmd->ethaddr, 6); 13440d163575Sopenharmony_ci if (netif != NULL) { 13450d163575Sopenharmony_ci ret = etharp_delete_arp_entry(netif, &ipaddr); 13460d163575Sopenharmony_ci } else { 13470d163575Sopenharmony_ci#ifdef LOSCFG_NET_CONTAINER 13480d163575Sopenharmony_ci for (netif = group->netif_list; netif != NULL; netif = netif->next) { 13490d163575Sopenharmony_ci#else 13500d163575Sopenharmony_ci for (netif = netif_list; netif != NULL; netif = netif->next) { 13510d163575Sopenharmony_ci#endif 13520d163575Sopenharmony_ci ret = etharp_delete_arp_entry(netif, &ipaddr); 13530d163575Sopenharmony_ci if (ret == ERR_OK) { 13540d163575Sopenharmony_ci /* only can del success one time */ 13550d163575Sopenharmony_ci break; 13560d163575Sopenharmony_ci } 13570d163575Sopenharmony_ci } 13580d163575Sopenharmony_ci } 13590d163575Sopenharmony_ci break; 13600d163575Sopenharmony_ci 13610d163575Sopenharmony_ci default: 13620d163575Sopenharmony_ci (void)snprintf_s(arp_cmd->cb_print_buf, PRINT_BUF_LEN, (PRINT_BUF_LEN - 1), "Error\n"); 13630d163575Sopenharmony_ci goto out; 13640d163575Sopenharmony_ci } 13650d163575Sopenharmony_ci 13660d163575Sopenharmony_ciout: 13670d163575Sopenharmony_ci if (type == ARP_OPTION_ADD || type == ARP_OPTION_DEL) { 13680d163575Sopenharmony_ci if (ret == ERR_MEM) { 13690d163575Sopenharmony_ci (void)snprintf_s(arp_cmd->cb_print_buf, PRINT_BUF_LEN, (PRINT_BUF_LEN - 1), "Out of memory error\n"); 13700d163575Sopenharmony_ci } else if (ret == ERR_ARG) { 13710d163575Sopenharmony_ci (void)snprintf_s(arp_cmd->cb_print_buf, PRINT_BUF_LEN, (PRINT_BUF_LEN - 1), "Illegal argument\n"); 13720d163575Sopenharmony_ci } else if (ret == ERR_RTE) { 13730d163575Sopenharmony_ci (void)snprintf_s(arp_cmd->cb_print_buf, PRINT_BUF_LEN, (PRINT_BUF_LEN - 1), "Network is unreachable\n"); 13740d163575Sopenharmony_ci } else { 13750d163575Sopenharmony_ci (void)snprintf_s(arp_cmd->cb_print_buf, PRINT_BUF_LEN, (PRINT_BUF_LEN - 1), "Succeeded\n"); 13760d163575Sopenharmony_ci } 13770d163575Sopenharmony_ci } 13780d163575Sopenharmony_ci#endif 13790d163575Sopenharmony_ci 13800d163575Sopenharmony_ci sys_sem_signal(&arp_cmd->cb_completed); 13810d163575Sopenharmony_ci} 13820d163575Sopenharmony_ci 13830d163575Sopenharmony_ci 13840d163575Sopenharmony_ciLWIP_STATIC void lwip_arp_usage(const char *cmd) 13850d163575Sopenharmony_ci{ 13860d163575Sopenharmony_ci PRINTK("Usage:" 13870d163575Sopenharmony_ci "\n%s" 13880d163575Sopenharmony_ci "\n%s [-i IF] -s IPADDR HWADDR" 13890d163575Sopenharmony_ci "\n%s [-i IF] -d IPADDR\n", 13900d163575Sopenharmony_ci cmd, cmd, cmd); 13910d163575Sopenharmony_ci} 13920d163575Sopenharmony_ci 13930d163575Sopenharmony_ciu32_t lwip_arp(int argc, const char **argv) 13940d163575Sopenharmony_ci{ 13950d163575Sopenharmony_ci int i; 13960d163575Sopenharmony_ci struct arp_option arp_cmd; 13970d163575Sopenharmony_ci err_t ret; 13980d163575Sopenharmony_ci size_t interface_len = 0; 13990d163575Sopenharmony_ci 14000d163575Sopenharmony_ci (void)memset_s(&arp_cmd, sizeof(struct arp_option), 0, sizeof(struct arp_option)); 14010d163575Sopenharmony_ci if (!tcpip_init_finish) { 14020d163575Sopenharmony_ci PRINTK("%s: tcpip_init have not been called\n", __FUNCTION__); 14030d163575Sopenharmony_ci return LOS_NOK; 14040d163575Sopenharmony_ci } 14050d163575Sopenharmony_ci 14060d163575Sopenharmony_ci arp_cmd.iface[0] = 'd'; 14070d163575Sopenharmony_ci arp_cmd.iface[1] = 'e'; 14080d163575Sopenharmony_ci arp_cmd.iface[2] = '0'; 14090d163575Sopenharmony_ci arp_cmd.option = ARP_OPTION_SHOW; 14100d163575Sopenharmony_ci arp_cmd.print_buf_len = 0; 14110d163575Sopenharmony_ci if (sys_sem_new(&arp_cmd.cb_completed, 0) != ERR_OK) { 14120d163575Sopenharmony_ci PRINTK("%s: sys_sem_new fail\n", __FUNCTION__); 14130d163575Sopenharmony_ci return 1; 14140d163575Sopenharmony_ci } 14150d163575Sopenharmony_ci 14160d163575Sopenharmony_ci i = 0; 14170d163575Sopenharmony_ci while (argc > 0) { 14180d163575Sopenharmony_ci if (strcmp("-i", argv[i]) == 0 && (argc > 1)) { 14190d163575Sopenharmony_ci /* get the network interface's name */ 14200d163575Sopenharmony_ci interface_len = strlen(argv[i + 1]); 14210d163575Sopenharmony_ci if (interface_len < IFNAMSIZ) { 14220d163575Sopenharmony_ci if (strncmp(argv[i + 1], "lo", (sizeof("lo") - 1)) == 0) { 14230d163575Sopenharmony_ci PRINTK("Illegal operation\n"); 14240d163575Sopenharmony_ci goto arp_error; 14250d163575Sopenharmony_ci } 14260d163575Sopenharmony_ci if (strncpy_s(arp_cmd.iface, IFNAMSIZ, argv[i + 1], interface_len) != EOK) { 14270d163575Sopenharmony_ci PRINTK("strncpy_s error\n"); 14280d163575Sopenharmony_ci goto arp_error; 14290d163575Sopenharmony_ci } 14300d163575Sopenharmony_ci arp_cmd.iface[interface_len] = '\0'; 14310d163575Sopenharmony_ci } else { 14320d163575Sopenharmony_ci PRINTK("Iface name is big \n"); 14330d163575Sopenharmony_ci goto arp_error; 14340d163575Sopenharmony_ci } 14350d163575Sopenharmony_ci i += 2; 14360d163575Sopenharmony_ci argc -= 2; // 2: number of used parameters 14370d163575Sopenharmony_ci } else if (strcmp("-d", argv[i]) == 0 && (argc > 1)) { 14380d163575Sopenharmony_ci /* arp delete */ 14390d163575Sopenharmony_ci arp_cmd.option = ARP_OPTION_DEL; 14400d163575Sopenharmony_ci arp_cmd.ipaddr = inet_addr(argv[i + 1]); 14410d163575Sopenharmony_ci 14420d163575Sopenharmony_ci if (arp_cmd.ipaddr == IPADDR_NONE) { 14430d163575Sopenharmony_ci PRINTK("IP address is not correct!\n"); 14440d163575Sopenharmony_ci goto arp_error; 14450d163575Sopenharmony_ci } 14460d163575Sopenharmony_ci 14470d163575Sopenharmony_ci i += 2; 14480d163575Sopenharmony_ci argc -= 2; // 2: number of used parameters 14490d163575Sopenharmony_ci } else if (strcmp("-s", argv[i]) == 0 && (argc > 2)) { // 2: require more than 2 parameters 14500d163575Sopenharmony_ci /* arp add */ 14510d163575Sopenharmony_ci char *digit = NULL; 14520d163575Sopenharmony_ci u32_t macaddrlen = strlen(argv[i + 2]) + 1; 14530d163575Sopenharmony_ci char tmpStr[MAX_MACADDR_STRING_LENGTH]; 14540d163575Sopenharmony_ci char *tmpStr1 = NULL; 14550d163575Sopenharmony_ci char *saveptr1 = NULL; 14560d163575Sopenharmony_ci char *temp = NULL; 14570d163575Sopenharmony_ci int j; 14580d163575Sopenharmony_ci 14590d163575Sopenharmony_ci arp_cmd.option = ARP_OPTION_ADD; 14600d163575Sopenharmony_ci arp_cmd.ipaddr = inet_addr(argv[i + 1]); 14610d163575Sopenharmony_ci 14620d163575Sopenharmony_ci if (arp_cmd.ipaddr == IPADDR_NONE) { 14630d163575Sopenharmony_ci PRINTK("IP address is not correct!\n"); 14640d163575Sopenharmony_ci goto arp_error; 14650d163575Sopenharmony_ci } 14660d163575Sopenharmony_ci 14670d163575Sopenharmony_ci /* cannot add an arp entry of 127.*.*.* */ 14680d163575Sopenharmony_ci if ((arp_cmd.ipaddr & (u32_t)0x0000007fUL) == (u32_t)0x0000007fUL) { 14690d163575Sopenharmony_ci PRINTK("IP address is not correct!\n"); 14700d163575Sopenharmony_ci goto arp_error; 14710d163575Sopenharmony_ci } 14720d163575Sopenharmony_ci 14730d163575Sopenharmony_ci if (macaddrlen != MAX_MACADDR_STRING_LENGTH) { 14740d163575Sopenharmony_ci PRINTK("Wrong MAC address length\n"); 14750d163575Sopenharmony_ci goto arp_error; 14760d163575Sopenharmony_ci } 14770d163575Sopenharmony_ci 14780d163575Sopenharmony_ci if (strncpy_s(tmpStr, MAX_MACADDR_STRING_LENGTH, argv[i + 2], macaddrlen - 1) != 0) { 14790d163575Sopenharmony_ci PRINTK("Wrong MAC address\n"); 14800d163575Sopenharmony_ci goto arp_error; 14810d163575Sopenharmony_ci } 14820d163575Sopenharmony_ci 14830d163575Sopenharmony_ci for (j = 0, tmpStr1 = tmpStr; j < 6; j++, tmpStr1 = NULL) { 14840d163575Sopenharmony_ci digit = strtok_r(tmpStr1, ":", &saveptr1); 14850d163575Sopenharmony_ci if ((digit == NULL) || (strlen(digit) > 2)) { 14860d163575Sopenharmony_ci PRINTK("MAC address is not correct\n"); 14870d163575Sopenharmony_ci goto arp_error; 14880d163575Sopenharmony_ci } 14890d163575Sopenharmony_ci 14900d163575Sopenharmony_ci for (temp = digit; *temp != '\0'; temp++) { 14910d163575Sopenharmony_ci if (!isxdigit(*temp)) { 14920d163575Sopenharmony_ci PRINTK("MAC address is not correct\n"); 14930d163575Sopenharmony_ci goto arp_error; 14940d163575Sopenharmony_ci } 14950d163575Sopenharmony_ci } 14960d163575Sopenharmony_ci 14970d163575Sopenharmony_ci CONVERT_STRING_TO_HEX(digit, arp_cmd.ethaddr[j]); 14980d163575Sopenharmony_ci } 14990d163575Sopenharmony_ci 15000d163575Sopenharmony_ci i += 3; 15010d163575Sopenharmony_ci argc -= 3; // 3: number of used parameters 15020d163575Sopenharmony_ci } else { 15030d163575Sopenharmony_ci goto arp_error; 15040d163575Sopenharmony_ci } 15050d163575Sopenharmony_ci } 15060d163575Sopenharmony_ci 15070d163575Sopenharmony_ci ret = tcpip_callback(lwip_arp_internal, &arp_cmd); 15080d163575Sopenharmony_ci if (ret != ERR_OK) { 15090d163575Sopenharmony_ci PRINTK("%s : tcpip_callback failed in line %d : errnu %d", __FUNCTION__, __LINE__, ret); 15100d163575Sopenharmony_ci sys_sem_free(&arp_cmd.cb_completed); 15110d163575Sopenharmony_ci return 1; 15120d163575Sopenharmony_ci } 15130d163575Sopenharmony_ci (void)sys_arch_sem_wait(&arp_cmd.cb_completed, 0); 15140d163575Sopenharmony_ci sys_sem_free(&arp_cmd.cb_completed); 15150d163575Sopenharmony_ci arp_cmd.cb_print_buf[PRINT_BUF_LEN - 1] = '\0'; 15160d163575Sopenharmony_ci PRINTK("%s", arp_cmd.cb_print_buf); 15170d163575Sopenharmony_ci return 0; 15180d163575Sopenharmony_ci 15190d163575Sopenharmony_ciarp_error: 15200d163575Sopenharmony_ci lwip_arp_usage("arp"); 15210d163575Sopenharmony_ci sys_sem_free(&arp_cmd.cb_completed); 15220d163575Sopenharmony_ci return 1; 15230d163575Sopenharmony_ci} 15240d163575Sopenharmony_ci 15250d163575Sopenharmony_ci#ifdef LOSCFG_SHELL_CMD_DEBUG 15260d163575Sopenharmony_ciSHELLCMD_ENTRY(arp_shellcmd, CMD_TYPE_EX, "arp", 1, (CmdCallBackFunc)lwip_arp); 15270d163575Sopenharmony_ci#endif /* LOSCFG_SHELL_CMD_DEBUG */ 15280d163575Sopenharmony_ci 15290d163575Sopenharmony_civoid ifup_internal(void *arg) 15300d163575Sopenharmony_ci{ 15310d163575Sopenharmony_ci struct netif *netif = NULL; 15320d163575Sopenharmony_ci struct if_cmd_data *ifcmd_data; 15330d163575Sopenharmony_ci 15340d163575Sopenharmony_ci ifcmd_data = (struct if_cmd_data *)arg; 15350d163575Sopenharmony_ci if (ifcmd_data == NULL) { 15360d163575Sopenharmony_ci return; 15370d163575Sopenharmony_ci } 15380d163575Sopenharmony_ci netif = netif_find(ifcmd_data->if_name); 15390d163575Sopenharmony_ci if (netif == NULL) { 15400d163575Sopenharmony_ci ifcmd_data->err = ERR_VAL; 15410d163575Sopenharmony_ci } else { 15420d163575Sopenharmony_ci (void)netif_set_up(netif); 15430d163575Sopenharmony_ci ifcmd_data->err = ERR_OK; 15440d163575Sopenharmony_ci } 15450d163575Sopenharmony_ci 15460d163575Sopenharmony_ci sys_sem_signal(&ifcmd_data->cb_completed); 15470d163575Sopenharmony_ci} 15480d163575Sopenharmony_ci 15490d163575Sopenharmony_civoid ifdown_internal(void *arg) 15500d163575Sopenharmony_ci{ 15510d163575Sopenharmony_ci struct netif *netif = NULL; 15520d163575Sopenharmony_ci struct if_cmd_data *ifcmd_data = NULL; 15530d163575Sopenharmony_ci 15540d163575Sopenharmony_ci ifcmd_data = (struct if_cmd_data *)arg; 15550d163575Sopenharmony_ci if (ifcmd_data == NULL) { 15560d163575Sopenharmony_ci return; 15570d163575Sopenharmony_ci } 15580d163575Sopenharmony_ci netif = netif_find(ifcmd_data->if_name); 15590d163575Sopenharmony_ci if (netif == NULL) { 15600d163575Sopenharmony_ci ifcmd_data->err = ERR_VAL; 15610d163575Sopenharmony_ci } else { 15620d163575Sopenharmony_ci (void)netif_set_down(netif); 15630d163575Sopenharmony_ci ifcmd_data->err = ERR_OK; 15640d163575Sopenharmony_ci } 15650d163575Sopenharmony_ci 15660d163575Sopenharmony_ci sys_sem_signal(&ifcmd_data->cb_completed); 15670d163575Sopenharmony_ci} 15680d163575Sopenharmony_ci 15690d163575Sopenharmony_ci#if LWIP_DNS 15700d163575Sopenharmony_ci#ifndef LWIP_TESTBED 15710d163575Sopenharmony_ciLWIP_STATIC 15720d163575Sopenharmony_ci#endif 15730d163575Sopenharmony_cistruct hostent *gethostnameinfo(const char *host) 15740d163575Sopenharmony_ci{ 15750d163575Sopenharmony_ci static struct hostent hostbuf; 15760d163575Sopenharmony_ci struct hostent *hp = NULL; 15770d163575Sopenharmony_ci const size_t hstbuflen = 1024; 15780d163575Sopenharmony_ci char tmphstbuf[1024]; 15790d163575Sopenharmony_ci int res; 15800d163575Sopenharmony_ci int herr; 15810d163575Sopenharmony_ci 15820d163575Sopenharmony_ci res = lwip_gethostbyname_r(host, &hostbuf, tmphstbuf, hstbuflen, &hp, &herr); 15830d163575Sopenharmony_ci /* Check for errors. */ 15840d163575Sopenharmony_ci if (res || hp == NULL) 15850d163575Sopenharmony_ci return NULL; 15860d163575Sopenharmony_ci return hp; 15870d163575Sopenharmony_ci} 15880d163575Sopenharmony_ci 15890d163575Sopenharmony_ciLWIP_STATIC unsigned int get_hostip(const char *hname) 15900d163575Sopenharmony_ci{ 15910d163575Sopenharmony_ci unsigned int ip = 0; 15920d163575Sopenharmony_ci int ret; 15930d163575Sopenharmony_ci 15940d163575Sopenharmony_ci struct hostent *pent = gethostnameinfo(hname); 15950d163575Sopenharmony_ci if (pent == NULL || pent->h_addr == NULL) 15960d163575Sopenharmony_ci return 0; 15970d163575Sopenharmony_ci ret = memcpy_s(&ip, sizeof(ip), pent->h_addr, 4); 15980d163575Sopenharmony_ci if (ret != 0) { 15990d163575Sopenharmony_ci return 0; 16000d163575Sopenharmony_ci } 16010d163575Sopenharmony_ci return ip; 16020d163575Sopenharmony_ci} 16030d163575Sopenharmony_ci#endif 16040d163575Sopenharmony_ci 16050d163575Sopenharmony_ci#if LWIP_EXT_POLL_SUPPORT 16060d163575Sopenharmony_cistatic int ping_taskid = -1; 16070d163575Sopenharmony_cistatic int ping_kill = 0; 16080d163575Sopenharmony_ci#define PING_ZERO_DATA_LEN 8 16090d163575Sopenharmony_cistatic void lwip_ping_usage(void) 16100d163575Sopenharmony_ci{ 16110d163575Sopenharmony_ci PRINTK("Usage:"\ 16120d163575Sopenharmony_ci "\n ping" 16130d163575Sopenharmony_ci "\n ping [-n cnt] [-w interval] [-l data_len] destination" 16140d163575Sopenharmony_ci "\n ping [-t] [-w interval] destination" 16150d163575Sopenharmony_ci "\n ping -k"); 16160d163575Sopenharmony_ci PRINTK("\n -t means ping forever, user can use -k to stop the forever ping\n"); 16170d163575Sopenharmony_ci} 16180d163575Sopenharmony_ci 16190d163575Sopenharmony_ciLWIP_STATIC int osPingFunc(u32_t destip, u32_t cnt, u32_t interval, u32_t data_len) 16200d163575Sopenharmony_ci{ 16210d163575Sopenharmony_ci int sfd; 16220d163575Sopenharmony_ci struct sockaddr_in to; 16230d163575Sopenharmony_ci struct pbuf *pbuf_resp = NULL; 16240d163575Sopenharmony_ci struct icmp_echo_hdr *iecho = NULL; 16250d163575Sopenharmony_ci struct icmp_echo_hdr *iecho_resp = NULL; 16260d163575Sopenharmony_ci struct ip_hdr *iphdr_resp = NULL; 16270d163575Sopenharmony_ci u32_t iecho_len; 16280d163575Sopenharmony_ci s16_t ip_hlen; 16290d163575Sopenharmony_ci u32_t forever; 16300d163575Sopenharmony_ci u32_t i = 0; 16310d163575Sopenharmony_ci u32_t succ_cnt = 0; 16320d163575Sopenharmony_ci u32_t failed_cnt = 0; 16330d163575Sopenharmony_ci struct timespec start, end; 16340d163575Sopenharmony_ci long timout_ms = 0; 16350d163575Sopenharmony_ci struct pollfd pfd; 16360d163575Sopenharmony_ci long rtt; 16370d163575Sopenharmony_ci int ret = 0; 16380d163575Sopenharmony_ci u32_t intrvl = 0; 16390d163575Sopenharmony_ci char *data_buf = NULL; 16400d163575Sopenharmony_ci BOOL timeout_flag = false; 16410d163575Sopenharmony_ci char buf[50]; 16420d163575Sopenharmony_ci 16430d163575Sopenharmony_ci iecho_len = sizeof(struct icmp_echo_hdr) + data_len; 16440d163575Sopenharmony_ci sfd = lwip_socket(PF_INET, SOCK_RAW, IPPROTO_ICMP); 16450d163575Sopenharmony_ci if (sfd < 0) { 16460d163575Sopenharmony_ci perror("Ping socket"); 16470d163575Sopenharmony_ci return -1; 16480d163575Sopenharmony_ci } 16490d163575Sopenharmony_ci pbuf_resp = pbuf_alloc(PBUF_RAW, IP_HLEN + sizeof(struct icmp_echo_hdr), PBUF_RAM); 16500d163575Sopenharmony_ci if (pbuf_resp == NULL) { 16510d163575Sopenharmony_ci PRINTK("Ping: pbuf_resp malloc failed\n"); 16520d163575Sopenharmony_ci ret = -1; 16530d163575Sopenharmony_ci goto FAILURE; 16540d163575Sopenharmony_ci } 16550d163575Sopenharmony_ci iecho = (struct icmp_echo_hdr *)mem_malloc(iecho_len); 16560d163575Sopenharmony_ci if (iecho == NULL) { 16570d163575Sopenharmony_ci PRINTK("Ping: echo request malloc failed\n"); 16580d163575Sopenharmony_ci ret = -1; 16590d163575Sopenharmony_ci goto FAILURE; 16600d163575Sopenharmony_ci } 16610d163575Sopenharmony_ci 16620d163575Sopenharmony_ci to.sin_family = AF_INET; 16630d163575Sopenharmony_ci to.sin_addr.s_addr = destip; /* already in network order */ 16640d163575Sopenharmony_ci to.sin_port = 0; 16650d163575Sopenharmony_ci 16660d163575Sopenharmony_ci if (data_len > PING_ZERO_DATA_LEN) { 16670d163575Sopenharmony_ci (void)memset_s(iecho, sizeof(struct icmp_echo_hdr) + PING_ZERO_DATA_LEN, 16680d163575Sopenharmony_ci 0, sizeof(struct icmp_echo_hdr) + PING_ZERO_DATA_LEN); 16690d163575Sopenharmony_ci data_buf = (char *)iecho + sizeof(struct icmp_echo_hdr) + PING_ZERO_DATA_LEN; 16700d163575Sopenharmony_ci for (i = 0; i < data_len - PING_ZERO_DATA_LEN; i++) { 16710d163575Sopenharmony_ci *(data_buf + i) = i + 0x10; 16720d163575Sopenharmony_ci } 16730d163575Sopenharmony_ci } else { 16740d163575Sopenharmony_ci (void)memset_s(iecho, sizeof(struct icmp_echo_hdr) + data_len, 0, sizeof(struct icmp_echo_hdr) + data_len); 16750d163575Sopenharmony_ci } 16760d163575Sopenharmony_ci iecho->id = htons((u16_t)LOS_CurTaskIDGet()); 16770d163575Sopenharmony_ci ICMPH_TYPE_SET(iecho, (u8_t)ICMP_ECHO); 16780d163575Sopenharmony_ci forever = (cnt ? 0 : 1); 16790d163575Sopenharmony_ci i = 0; 16800d163575Sopenharmony_ci while (!ping_kill && (forever || (i < cnt))) { 16810d163575Sopenharmony_ci iecho->seqno = htons((u16_t)i); 16820d163575Sopenharmony_ci iecho->chksum = 0; 16830d163575Sopenharmony_ci iecho->chksum = inet_chksum((void *)iecho, iecho_len); 16840d163575Sopenharmony_ci 16850d163575Sopenharmony_ci ret = sendto(sfd, iecho, iecho_len, 0, (struct sockaddr *)&to, (socklen_t)sizeof(to)); 16860d163575Sopenharmony_ci if (ret < 0) { 16870d163575Sopenharmony_ci perror("Ping: sending ICMP echo request failed\n"); 16880d163575Sopenharmony_ci goto FAILURE; 16890d163575Sopenharmony_ci } 16900d163575Sopenharmony_ci 16910d163575Sopenharmony_ci /* capture the start time to calculate RTT */ 16920d163575Sopenharmony_ci (void)clock_gettime(CLOCK_MONOTONIC_RAW, &start); 16930d163575Sopenharmony_ci 16940d163575Sopenharmony_ci /* poll for ICMP echo response msg */ 16950d163575Sopenharmony_ci pfd.fd = sfd; 16960d163575Sopenharmony_ci 16970d163575Sopenharmony_ci do { 16980d163575Sopenharmony_ci pfd.events = POLLIN; 16990d163575Sopenharmony_ci pfd.revents = 0; 17000d163575Sopenharmony_ci timeout_flag = false; 17010d163575Sopenharmony_ci ret = poll(&pfd, 1, LWIP_SHELL_CMD_PING_TIMEOUT); 17020d163575Sopenharmony_ci if (ret < 0) { 17030d163575Sopenharmony_ci perror("Ping: poll\n"); 17040d163575Sopenharmony_ci goto FAILURE; 17050d163575Sopenharmony_ci } else if (ret == 0) { 17060d163575Sopenharmony_ci /* first type timeout event */ 17070d163575Sopenharmony_ci timeout_flag = true; 17080d163575Sopenharmony_ci break; 17090d163575Sopenharmony_ci } 17100d163575Sopenharmony_ci 17110d163575Sopenharmony_ci ret = recv(sfd, pbuf_resp->payload, pbuf_resp->len, MSG_DONTWAIT); 17120d163575Sopenharmony_ci if (ret < 0) { 17130d163575Sopenharmony_ci perror("Ping: recv echo reply failed\n"); 17140d163575Sopenharmony_ci goto FAILURE; 17150d163575Sopenharmony_ci } 17160d163575Sopenharmony_ci 17170d163575Sopenharmony_ci /* Accessing ip header and icmp header */ 17180d163575Sopenharmony_ci iphdr_resp = pbuf_resp->payload; 17190d163575Sopenharmony_ci 17200d163575Sopenharmony_ci ip_hlen = (IPH_HL(iphdr_resp) << 2); 17210d163575Sopenharmony_ci if (pbuf_header(pbuf_resp, -ip_hlen)) { 17220d163575Sopenharmony_ci /* this failure will never happen, but failure handle is written just to be in safe side */ 17230d163575Sopenharmony_ci PRINTK("Ping : memory management failure\n"); 17240d163575Sopenharmony_ci goto FAILURE; 17250d163575Sopenharmony_ci } 17260d163575Sopenharmony_ci iecho_resp = (struct icmp_echo_hdr *)pbuf_resp->payload; 17270d163575Sopenharmony_ci /* Reverting back pbuf to its original state */ 17280d163575Sopenharmony_ci if (pbuf_header(pbuf_resp, ip_hlen)) { 17290d163575Sopenharmony_ci /* this failure will never happen, but failure handle is written just to be in safe side */ 17300d163575Sopenharmony_ci PRINTK("ping : memory management failure\n"); 17310d163575Sopenharmony_ci goto FAILURE; 17320d163575Sopenharmony_ci } 17330d163575Sopenharmony_ci 17340d163575Sopenharmony_ci if ((iphdr_resp->src.addr != to.sin_addr.s_addr) || 17350d163575Sopenharmony_ci ((ICMPH_TYPE(iecho_resp) == ICMP_ECHO) && (iphdr_resp->src.addr == to.sin_addr.s_addr))) { 17360d163575Sopenharmony_ci /* second type timeout event */ 17370d163575Sopenharmony_ci (void)clock_gettime(CLOCK_MONOTONIC_RAW, &end); 17380d163575Sopenharmony_ci timout_ms = ((end.tv_sec - start.tv_sec) * 1000 + (end.tv_nsec - start.tv_nsec) / 1000000); 17390d163575Sopenharmony_ci timout_ms = LWIP_SHELL_CMD_PING_TIMEOUT - timout_ms; 17400d163575Sopenharmony_ci } else { 17410d163575Sopenharmony_ci timout_ms = 0; 17420d163575Sopenharmony_ci break; 17430d163575Sopenharmony_ci } 17440d163575Sopenharmony_ci } while (timout_ms >= 0); 17450d163575Sopenharmony_ci 17460d163575Sopenharmony_ci /* all timeout events are true timeout */ 17470d163575Sopenharmony_ci if ((timout_ms < 0) || (timeout_flag == true)) { 17480d163575Sopenharmony_ci failed_cnt++; 17490d163575Sopenharmony_ci i++; 17500d163575Sopenharmony_ci PRINTK("\nPing: destination unreachable ..."); 17510d163575Sopenharmony_ci continue; 17520d163575Sopenharmony_ci } 17530d163575Sopenharmony_ci /* capture the end time to calculate round trip time */ 17540d163575Sopenharmony_ci (void)clock_gettime(CLOCK_MONOTONIC_RAW, &end); 17550d163575Sopenharmony_ci rtt = ((end.tv_sec - start.tv_sec) * 1000 + (end.tv_nsec - start.tv_nsec) / 1000000); 17560d163575Sopenharmony_ci 17570d163575Sopenharmony_ci if (iphdr_resp->src.addr == to.sin_addr.s_addr) { 17580d163575Sopenharmony_ci switch (ICMPH_TYPE(iecho_resp)) { 17590d163575Sopenharmony_ci case ICMP_ER: 17600d163575Sopenharmony_ci PRINTK("\n[%u]Reply from %s: ", i, inet_ntop(AF_INET, &to.sin_addr, buf, sizeof(buf))); 17610d163575Sopenharmony_ci if (rtt > 0) { 17620d163575Sopenharmony_ci PRINTK("time=%ims ", rtt); 17630d163575Sopenharmony_ci } else { 17640d163575Sopenharmony_ci PRINTK("time<1ms "); 17650d163575Sopenharmony_ci } 17660d163575Sopenharmony_ci PRINTK("TTL=%u", iphdr_resp->_ttl); 17670d163575Sopenharmony_ci 17680d163575Sopenharmony_ci /* delay 1s for every successful ping */ 17690d163575Sopenharmony_ci intrvl = interval; 17700d163575Sopenharmony_ci do { 17710d163575Sopenharmony_ci if (intrvl < 1000) { 17720d163575Sopenharmony_ci sys_msleep(intrvl); 17730d163575Sopenharmony_ci break; 17740d163575Sopenharmony_ci } 17750d163575Sopenharmony_ci intrvl -= 1000; 17760d163575Sopenharmony_ci sys_msleep(1000); // 1000: delay 1 s 17770d163575Sopenharmony_ci if (ping_kill == 1) 17780d163575Sopenharmony_ci break; 17790d163575Sopenharmony_ci } while (intrvl > 0); 17800d163575Sopenharmony_ci succ_cnt++; 17810d163575Sopenharmony_ci break; 17820d163575Sopenharmony_ci case ICMP_DUR: 17830d163575Sopenharmony_ci PRINTK("\nPing: destination host unreachable ..."); 17840d163575Sopenharmony_ci break; 17850d163575Sopenharmony_ci case ICMP_SQ: 17860d163575Sopenharmony_ci PRINTK("\nPing: source quench ..."); 17870d163575Sopenharmony_ci break; 17880d163575Sopenharmony_ci case ICMP_RD: 17890d163575Sopenharmony_ci PRINTK("\nPing: redirect ..."); 17900d163575Sopenharmony_ci break; 17910d163575Sopenharmony_ci case ICMP_TE: 17920d163575Sopenharmony_ci PRINTK("\nPing: time exceeded ..."); 17930d163575Sopenharmony_ci break; 17940d163575Sopenharmony_ci case ICMP_PP: 17950d163575Sopenharmony_ci PRINTK("\nPing: parameter problem ..."); 17960d163575Sopenharmony_ci break; 17970d163575Sopenharmony_ci default : 17980d163575Sopenharmony_ci PRINTK("\nPing: unknown error ..."); 17990d163575Sopenharmony_ci break; 18000d163575Sopenharmony_ci } 18010d163575Sopenharmony_ci i++; 18020d163575Sopenharmony_ci } 18030d163575Sopenharmony_ci } 18040d163575Sopenharmony_ci 18050d163575Sopenharmony_ci PRINTK("\n--- %s ping statistics ---\n", inet_ntop(AF_INET, &to.sin_addr, buf, sizeof(buf))); 18060d163575Sopenharmony_ci PRINTK("%u packets transmitted, %u received, %u loss\n", i, succ_cnt, failed_cnt); 18070d163575Sopenharmony_ci 18080d163575Sopenharmony_ciFAILURE: 18090d163575Sopenharmony_ci ping_kill = 0; 18100d163575Sopenharmony_ci (void)lwip_close(sfd); 18110d163575Sopenharmony_ci if (pbuf_resp != NULL) { 18120d163575Sopenharmony_ci (void)pbuf_free(pbuf_resp); 18130d163575Sopenharmony_ci } 18140d163575Sopenharmony_ci if (iecho != NULL) { 18150d163575Sopenharmony_ci mem_free(iecho); 18160d163575Sopenharmony_ci } 18170d163575Sopenharmony_ci return ret; 18180d163575Sopenharmony_ci} 18190d163575Sopenharmony_ci 18200d163575Sopenharmony_cistatic void ping_cmd(unsigned int p0, unsigned int p1, unsigned int p2, unsigned int p3) 18210d163575Sopenharmony_ci{ 18220d163575Sopenharmony_ci u32_t destip = p0; 18230d163575Sopenharmony_ci u32_t count = p1; 18240d163575Sopenharmony_ci u32_t interval = p2; 18250d163575Sopenharmony_ci u32_t data_len = p3; 18260d163575Sopenharmony_ci int ret; 18270d163575Sopenharmony_ci 18280d163575Sopenharmony_ci ret = osPingFunc(destip, count, interval, data_len); 18290d163575Sopenharmony_ci if (ret < 0) { 18300d163575Sopenharmony_ci PRINTK("Ping cmd failed due to some errors\n"); 18310d163575Sopenharmony_ci } 18320d163575Sopenharmony_ci 18330d163575Sopenharmony_ci ping_taskid = -1; 18340d163575Sopenharmony_ci} 18350d163575Sopenharmony_ci 18360d163575Sopenharmony_ciu32_t osShellPing(int argc, const char **argv) 18370d163575Sopenharmony_ci{ 18380d163575Sopenharmony_ci int ret; 18390d163575Sopenharmony_ci u32_t i = 0; 18400d163575Sopenharmony_ci u32_t count = 0; 18410d163575Sopenharmony_ci int count_set = 0; 18420d163575Sopenharmony_ci u32_t interval = 1000; /* default ping interval */ 18430d163575Sopenharmony_ci u32_t data_len = 48; /* default data length */ 18440d163575Sopenharmony_ci ip4_addr_t dst_ipaddr; 18450d163575Sopenharmony_ci TSK_INIT_PARAM_S stPingTask; 18460d163575Sopenharmony_ci 18470d163575Sopenharmony_ci if (!tcpip_init_finish) { 18480d163575Sopenharmony_ci PRINTK("Ping: tcpip_init have not been called\n"); 18490d163575Sopenharmony_ci return LOS_NOK; 18500d163575Sopenharmony_ci } 18510d163575Sopenharmony_ci 18520d163575Sopenharmony_ci if ((argc < 1) || (argv == NULL)) { 18530d163575Sopenharmony_ci PRINTK("Ping: require dest ipaddr at least\n"); 18540d163575Sopenharmony_ci goto ping_error; 18550d163575Sopenharmony_ci } 18560d163575Sopenharmony_ci 18570d163575Sopenharmony_ci /* could add more param support */ 18580d163575Sopenharmony_ci while (argc > 0) { 18590d163575Sopenharmony_ci if (strcmp("-n", argv[i]) == 0 && (argc > 1)) { 18600d163575Sopenharmony_ci ret = atoi(argv[i + 1]); 18610d163575Sopenharmony_ci if (ret <= 0) { 18620d163575Sopenharmony_ci PRINTK("Ping count should be greater than 0 \n"); 18630d163575Sopenharmony_ci goto ping_error; 18640d163575Sopenharmony_ci } 18650d163575Sopenharmony_ci count = ret; 18660d163575Sopenharmony_ci count_set = 1; 18670d163575Sopenharmony_ci i += 2; 18680d163575Sopenharmony_ci argc -= 2; // 2: nuber of arguments that has been checked 18690d163575Sopenharmony_ci } else if (strcmp("-t", argv[i]) == 0) { 18700d163575Sopenharmony_ci count = 0; /* ping forerver */ 18710d163575Sopenharmony_ci count_set = 1; 18720d163575Sopenharmony_ci i++; 18730d163575Sopenharmony_ci argc--; 18740d163575Sopenharmony_ci } else if (strcmp("-w", argv[i]) == 0 && (argc > 1)) { 18750d163575Sopenharmony_ci ret = atoi(argv[i + 1]); 18760d163575Sopenharmony_ci if (ret <= 0) { 18770d163575Sopenharmony_ci PRINTK("Ping interval should be greater than 0 \n"); 18780d163575Sopenharmony_ci goto ping_error; 18790d163575Sopenharmony_ci } 18800d163575Sopenharmony_ci 18810d163575Sopenharmony_ci interval = ret; 18820d163575Sopenharmony_ci i += 2; 18830d163575Sopenharmony_ci argc -= 2; // 2:number of arguments that has been checked 18840d163575Sopenharmony_ci } else if (strcmp("-l", argv[i]) == 0 && (argc > 1)) { 18850d163575Sopenharmony_ci ret = atoi(argv[i + 1]); 18860d163575Sopenharmony_ci if (ret < 0 || ret > (int)(LWIP_MAX_UDP_RAW_SEND_SIZE - sizeof(struct icmp_echo_hdr))) { 18870d163575Sopenharmony_ci PRINTK("Ping data length error, should be in range of [0, %d] \n", 18880d163575Sopenharmony_ci LWIP_MAX_UDP_RAW_SEND_SIZE - sizeof(struct icmp_echo_hdr)); 18890d163575Sopenharmony_ci goto ping_error; 18900d163575Sopenharmony_ci } 18910d163575Sopenharmony_ci data_len = ret; 18920d163575Sopenharmony_ci i += 2; 18930d163575Sopenharmony_ci argc -= 2; // 2: number of elements has been checked 18940d163575Sopenharmony_ci } else if (strcmp("-k", argv[i]) == 0) { 18950d163575Sopenharmony_ci if (ping_taskid > 0) { 18960d163575Sopenharmony_ci ping_kill = 1; /* stop the current ping task */ 18970d163575Sopenharmony_ci return LOS_OK; 18980d163575Sopenharmony_ci } else { 18990d163575Sopenharmony_ci PRINTK("No ping task running...\n"); 19000d163575Sopenharmony_ci return LOS_NOK; 19010d163575Sopenharmony_ci } 19020d163575Sopenharmony_ci } else { 19030d163575Sopenharmony_ci if (argc == 1) { 19040d163575Sopenharmony_ci break; 19050d163575Sopenharmony_ci } else { 19060d163575Sopenharmony_ci PRINTK("Invalid Ping param\n"); 19070d163575Sopenharmony_ci goto ping_error; 19080d163575Sopenharmony_ci } 19090d163575Sopenharmony_ci } 19100d163575Sopenharmony_ci } 19110d163575Sopenharmony_ci 19120d163575Sopenharmony_ci if (!count_set) { 19130d163575Sopenharmony_ci count = LWIP_SHELL_CMD_PING_RETRY_TIMES; 19140d163575Sopenharmony_ci } 19150d163575Sopenharmony_ci 19160d163575Sopenharmony_ci /* initialize dst IP address */ 19170d163575Sopenharmony_ci if (argc <= 0) { 19180d163575Sopenharmony_ci goto ping_error; 19190d163575Sopenharmony_ci } 19200d163575Sopenharmony_ci#if LWIP_DNS 19210d163575Sopenharmony_ci dst_ipaddr.addr = get_hostip(argv[i]); 19220d163575Sopenharmony_ci#else /* LWIP_DNS */ 19230d163575Sopenharmony_ci dst_ipaddr.addr = inet_addr(argv[i]); 19240d163575Sopenharmony_ci#endif /* LWIP_DNS */ 19250d163575Sopenharmony_ci 19260d163575Sopenharmony_ci if (dst_ipaddr.addr == IPADDR_NONE || dst_ipaddr.addr == IPADDR_ANY) { 19270d163575Sopenharmony_ci PRINTK("Invalid dest ipaddr: NONE or ANY\n"); 19280d163575Sopenharmony_ci return LOS_NOK; 19290d163575Sopenharmony_ci } 19300d163575Sopenharmony_ci 19310d163575Sopenharmony_ci /* start one task if ping forever or ping count greater than 60 */ 19320d163575Sopenharmony_ci if (count == 0 || count > LWIP_SHELL_CMD_PING_RETRY_TIMES) { 19330d163575Sopenharmony_ci if (ping_taskid > 0) { 19340d163575Sopenharmony_ci PRINTK("Ping task already running and only support one now\n"); 19350d163575Sopenharmony_ci return LOS_NOK; 19360d163575Sopenharmony_ci } 19370d163575Sopenharmony_ci stPingTask.pfnTaskEntry = (TSK_ENTRY_FUNC)ping_cmd; 19380d163575Sopenharmony_ci stPingTask.uwStackSize = LOSCFG_BASE_CORE_TSK_DEFAULT_STACK_SIZE; 19390d163575Sopenharmony_ci stPingTask.pcName = "ping_task"; 19400d163575Sopenharmony_ci stPingTask.usTaskPrio = 8; /* higher than shell */ 19410d163575Sopenharmony_ci stPingTask.uwResved = LOS_TASK_STATUS_DETACHED; 19420d163575Sopenharmony_ci stPingTask.auwArgs[0] = dst_ipaddr.addr; /* network order */ 19430d163575Sopenharmony_ci stPingTask.auwArgs[1] = count; 19440d163575Sopenharmony_ci stPingTask.auwArgs[2] = interval; 19450d163575Sopenharmony_ci stPingTask.auwArgs[3] = data_len; // 3: index of data length 19460d163575Sopenharmony_ci ret = LOS_TaskCreate((UINT32 *)(&ping_taskid), &stPingTask); 19470d163575Sopenharmony_ci if (ret != LOS_OK) { 19480d163575Sopenharmony_ci PRINTK("ping_task create failed 0x%08x.\n", ret); 19490d163575Sopenharmony_ci count = LWIP_SHELL_CMD_PING_RETRY_TIMES; 19500d163575Sopenharmony_ci } else { 19510d163575Sopenharmony_ci return LOS_OK; 19520d163575Sopenharmony_ci } 19530d163575Sopenharmony_ci } 19540d163575Sopenharmony_ci 19550d163575Sopenharmony_ci /* two cases: 19560d163575Sopenharmony_ci 1, ping cout less than LWIP_SHELL_CMD_PING_RETRY_TIMES; 19570d163575Sopenharmony_ci 2, ping task create failed; 19580d163575Sopenharmony_ci */ 19590d163575Sopenharmony_ci if (osPingFunc(dst_ipaddr.addr, count, interval, data_len) < 0) { 19600d163575Sopenharmony_ci PRINTK("Ping cmd failed due some errors\n"); 19610d163575Sopenharmony_ci } 19620d163575Sopenharmony_ci 19630d163575Sopenharmony_ci return LOS_OK; 19640d163575Sopenharmony_ciping_error: 19650d163575Sopenharmony_ci lwip_ping_usage(); 19660d163575Sopenharmony_ci return LOS_NOK; 19670d163575Sopenharmony_ci} 19680d163575Sopenharmony_ci#ifdef LOSCFG_SHELL 19690d163575Sopenharmony_ciSHELLCMD_ENTRY(ping_shellcmd, CMD_TYPE_EX, "ping", XARGS, (CmdCallBackFunc)osShellPing); 19700d163575Sopenharmony_ci#endif /* LOSCFG_SHELL */ 19710d163575Sopenharmony_ci 19720d163575Sopenharmony_ci#else /* LWIP_EXT_POLL_SUPPORT */ 19730d163575Sopenharmony_ci 19740d163575Sopenharmony_ciu32_t osShellPing(int argc, const char **argv) 19750d163575Sopenharmony_ci{ 19760d163575Sopenharmony_ci int sfd; 19770d163575Sopenharmony_ci struct sockaddr_in to; 19780d163575Sopenharmony_ci struct icmp_echo_hdr iecho; 19790d163575Sopenharmony_ci struct pbuf *pbuf_resp = NULL; 19800d163575Sopenharmony_ci struct icmp_echo_hdr *iecho_resp = NULL; 19810d163575Sopenharmony_ci struct ip_hdr *iphdr_resp = NULL; 19820d163575Sopenharmony_ci s16_t ip_hlen; 19830d163575Sopenharmony_ci ip_addr_t dst_ipaddr; 19840d163575Sopenharmony_ci fd_set fdReadSet; 19850d163575Sopenharmony_ci struct timeval stTimeVal; 19860d163575Sopenharmony_ci struct timespec start, end; 19870d163575Sopenharmony_ci int ret; 19880d163575Sopenharmony_ci s32_t i; 19890d163575Sopenharmony_ci long rtt; 19900d163575Sopenharmony_ci s32_t pingcount; 19910d163575Sopenharmony_ci char buf[50]; 19920d163575Sopenharmony_ci 19930d163575Sopenharmony_ci if (!tcpip_init_finish) { 19940d163575Sopenharmony_ci PRINTK("ping: tcpip_init have not been called\n"); 19950d163575Sopenharmony_ci return LOS_NOK; 19960d163575Sopenharmony_ci } 19970d163575Sopenharmony_ci 19980d163575Sopenharmony_ci if ((argc < 1) || (argv == NULL)) { 19990d163575Sopenharmony_ci PRINTK("ping : invalid arguments, ping command receives ip as command line argument \n"); 20000d163575Sopenharmony_ci return LOS_NOK; 20010d163575Sopenharmony_ci } 20020d163575Sopenharmony_ci 20030d163575Sopenharmony_ci if (argc == 2) { 20040d163575Sopenharmony_ci pingcount = atoi(argv[1]); 20050d163575Sopenharmony_ci if (pingcount < 1) 20060d163575Sopenharmony_ci pingcount = LWIP_SHELL_CMD_PING_RETRY_TIMES; 20070d163575Sopenharmony_ci } else { 20080d163575Sopenharmony_ci pingcount = LWIP_SHELL_CMD_PING_RETRY_TIMES; 20090d163575Sopenharmony_ci } 20100d163575Sopenharmony_ci PRINTK("ping %u packets start.\n", pingcount); 20110d163575Sopenharmony_ci 20120d163575Sopenharmony_ci /* initialize dst IP address */ 20130d163575Sopenharmony_ci#if LWIP_DNS 20140d163575Sopenharmony_ci ip_2_ip4(&dst_ipaddr)->addr = get_hostip(argv[0]); 20150d163575Sopenharmony_ci#else /* LWIP_DNS */ 20160d163575Sopenharmony_ci ip_2_ip4(&dst_ipaddr)->addr = inet_addr(argv[0]); 20170d163575Sopenharmony_ci#endif /* LWIP_DNS */ 20180d163575Sopenharmony_ci 20190d163575Sopenharmony_ci to.sin_family = AF_INET; 20200d163575Sopenharmony_ci to.sin_addr.s_addr = ip_2_ip4(&dst_ipaddr)->addr; 20210d163575Sopenharmony_ci to.sin_port = 0; 20220d163575Sopenharmony_ci 20230d163575Sopenharmony_ci if (to.sin_addr.s_addr == IPADDR_NONE || to.sin_addr.s_addr == IPADDR_ANY) { 20240d163575Sopenharmony_ci PRINTK("ping : invalid ip address : NONE or ANY\n"); 20250d163575Sopenharmony_ci return LOS_NOK; 20260d163575Sopenharmony_ci } 20270d163575Sopenharmony_ci 20280d163575Sopenharmony_ci sfd = lwip_socket(PF_INET, SOCK_RAW, IPPROTO_ICMP); 20290d163575Sopenharmony_ci if (sfd == -1) { 20300d163575Sopenharmony_ci PRINTK("ping : failed, socket creation failed\n"); 20310d163575Sopenharmony_ci return LOS_NOK; 20320d163575Sopenharmony_ci } 20330d163575Sopenharmony_ci 20340d163575Sopenharmony_ci pbuf_resp = pbuf_alloc(PBUF_RAW, IP_HLEN + sizeof(struct icmp_echo_hdr), PBUF_RAM); 20350d163575Sopenharmony_ci if (pbuf_resp == NULL) { 20360d163575Sopenharmony_ci PRINTK("ping : memory allocation failed\n"); 20370d163575Sopenharmony_ci goto FAILURE; 20380d163575Sopenharmony_ci } 20390d163575Sopenharmony_ci 20400d163575Sopenharmony_ci for (i = 0; i < pingcount; i++) { 20410d163575Sopenharmony_ci (void)memset_s(&iecho, sizeof(iecho), 0, sizeof(iecho)); 20420d163575Sopenharmony_ci ICMPH_TYPE_SET(&iecho, (u8_t)ICMP_ECHO); 20430d163575Sopenharmony_ci iecho.chksum = inet_chksum(&iecho, sizeof(struct icmp_echo_hdr)); 20440d163575Sopenharmony_ci 20450d163575Sopenharmony_ci ret = lwip_sendto(sfd, &iecho, sizeof(struct icmp_echo_hdr), 0, (struct sockaddr *)&to, (socklen_t)sizeof(to)); 20460d163575Sopenharmony_ci if (ret == -1) { 20470d163575Sopenharmony_ci PRINTK("ping : sending ICMP echo msg failed\n"); 20480d163575Sopenharmony_ci goto FAILURE; 20490d163575Sopenharmony_ci } 20500d163575Sopenharmony_ci 20510d163575Sopenharmony_ci /* capture the start time to calculate round trip time */ 20520d163575Sopenharmony_ci (void)clock_gettime(CLOCK_MONOTONIC_RAW, &start); 20530d163575Sopenharmony_ci /* Wait in select for ICMP response msg */ 20540d163575Sopenharmony_ci FD_ZERO(&fdReadSet); 20550d163575Sopenharmony_ci FD_SET(sfd, &fdReadSet); 20560d163575Sopenharmony_ci stTimeVal.tv_sec = LWIP_SHELL_CMD_PING_TIMEOUT / 1000; 20570d163575Sopenharmony_ci stTimeVal.tv_usec = 0; 20580d163575Sopenharmony_ci 20590d163575Sopenharmony_ciDO_SELECT: 20600d163575Sopenharmony_ci ret = select(sfd + 1, &fdReadSet, 0, 0, &stTimeVal); 20610d163575Sopenharmony_ci if (ret < 0) { 20620d163575Sopenharmony_ci PRINTK("ping : select failure\n"); 20630d163575Sopenharmony_ci goto FAILURE; 20640d163575Sopenharmony_ci } else if (ret == 0) { 20650d163575Sopenharmony_ci PRINTK("Request timed out.\n"); 20660d163575Sopenharmony_ci continue; 20670d163575Sopenharmony_ci } 20680d163575Sopenharmony_ci 20690d163575Sopenharmony_ci /* capture the end time to calculate round trip time */ 20700d163575Sopenharmony_ci (void)clock_gettime(CLOCK_MONOTONIC_RAW, &end); 20710d163575Sopenharmony_ci rtt = ((end.tv_sec - start.tv_sec) * 1000 + (end.tv_nsec - start.tv_nsec) / 1000000); 20720d163575Sopenharmony_ci 20730d163575Sopenharmony_ci ret = lwip_recv(sfd, pbuf_resp->payload, pbuf_resp->len, 0); 20740d163575Sopenharmony_ci if (ret == -1) { 20750d163575Sopenharmony_ci PRINTK("ping : receiving ICMP echo response msg failed\n"); 20760d163575Sopenharmony_ci goto FAILURE; 20770d163575Sopenharmony_ci } 20780d163575Sopenharmony_ci 20790d163575Sopenharmony_ci /* Accessing ip header and icmp header */ 20800d163575Sopenharmony_ci iphdr_resp = (struct ip_hdr *)(pbuf_resp->payload); 20810d163575Sopenharmony_ci ip_hlen = (s16_t)(IPH_HL(iphdr_resp) * 4); 20820d163575Sopenharmony_ci if (pbuf_header(pbuf_resp, (s16_t)(-ip_hlen))) { 20830d163575Sopenharmony_ci /* this failure will never happen, but failure handle is written just to be in safe side */ 20840d163575Sopenharmony_ci PRINTK("ping : memory management failure\n"); 20850d163575Sopenharmony_ci goto FAILURE; 20860d163575Sopenharmony_ci } 20870d163575Sopenharmony_ci iecho_resp = (struct icmp_echo_hdr *)pbuf_resp->payload; 20880d163575Sopenharmony_ci 20890d163575Sopenharmony_ci /* Reverting back pbuf to its original state */ 20900d163575Sopenharmony_ci if (pbuf_header(pbuf_resp, ip_hlen)) { 20910d163575Sopenharmony_ci /* this failure will never happen, but failure handle is written just to be in safe side */ 20920d163575Sopenharmony_ci PRINTK("ping : memory management failure\n"); 20930d163575Sopenharmony_ci goto FAILURE; 20940d163575Sopenharmony_ci } 20950d163575Sopenharmony_ci 20960d163575Sopenharmony_ci if (iphdr_resp->src.addr == to.sin_addr.s_addr) { 20970d163575Sopenharmony_ci if (ICMPH_TYPE(iecho_resp) == ICMP_ER) { 20980d163575Sopenharmony_ci PRINTK("[%u]Reply from %s: time=%ims TTL=%u\n", i, 20990d163575Sopenharmony_ci inet_ntoa_r(to.sin_addr.s_addr, buf, sizeof(buf)), rtt, iphdr_resp->_ttl); 21000d163575Sopenharmony_ci } else if (ICMPH_TYPE(iecho_resp) == ICMP_ECHO) { 21010d163575Sopenharmony_ci /* If ping self, stack will receive a ICMP_ECHO request message flowing a ICMP_ER reply message, 21020d163575Sopenharmony_ci and we need reply only, do select again */ 21030d163575Sopenharmony_ci goto DO_SELECT; 21040d163575Sopenharmony_ci } 21050d163575Sopenharmony_ci } 21060d163575Sopenharmony_ci } 21070d163575Sopenharmony_ci 21080d163575Sopenharmony_ci (void)lwip_close(sfd); 21090d163575Sopenharmony_ci (void)pbuf_free(pbuf_resp); 21100d163575Sopenharmony_ci return LOS_OK; 21110d163575Sopenharmony_ci 21120d163575Sopenharmony_ciFAILURE: 21130d163575Sopenharmony_ci (void)lwip_close(sfd); 21140d163575Sopenharmony_ci if (pbuf_resp != NULL) { 21150d163575Sopenharmony_ci (void)pbuf_free(pbuf_resp); 21160d163575Sopenharmony_ci } 21170d163575Sopenharmony_ci 21180d163575Sopenharmony_ci return LOS_NOK; 21190d163575Sopenharmony_ci} 21200d163575Sopenharmony_ci 21210d163575Sopenharmony_ci#ifdef LOSCFG_SHELL 21220d163575Sopenharmony_ciSHELLCMD_ENTRY(ping_shellcmd, CMD_TYPE_EX, "ping", XARGS, (CmdCallBackFunc)osShellPing); 21230d163575Sopenharmony_ci#endif /* LOSCFG_SHELL */ 21240d163575Sopenharmony_ci 21250d163575Sopenharmony_ci#endif /* LWIP_EXT_POLL_SUPPORT */ 21260d163575Sopenharmony_ci 21270d163575Sopenharmony_ci#if LWIP_IPV6 21280d163575Sopenharmony_ciu32_t osShellPing6(int argc, const char **argv) 21290d163575Sopenharmony_ci{ 21300d163575Sopenharmony_ci u16_t icmpv6_id; 21310d163575Sopenharmony_ci u16_t icmpv6_seq; 21320d163575Sopenharmony_ci u32_t nsent; 21330d163575Sopenharmony_ci u32_t nrecieve; 21340d163575Sopenharmony_ci u32_t last_received; 21350d163575Sopenharmony_ci struct timespec start, end, start_in_reply; 21360d163575Sopenharmony_ci struct timespec first, last; 21370d163575Sopenharmony_ci long rtt; 21380d163575Sopenharmony_ci int ret; 21390d163575Sopenharmony_ci fd_set fdReadSet; 21400d163575Sopenharmony_ci void *param = NULL; 21410d163575Sopenharmony_ci ping6_args_t ping6_params; 21420d163575Sopenharmony_ci ping6_stats_t ping6_stats; 21430d163575Sopenharmony_ci struct sockaddr_in6 to; 21440d163575Sopenharmony_ci struct icmp6_echo_hdr *iecho_resp = NULL; 21450d163575Sopenharmony_ci struct icmp6_echo_hdr *iecho = NULL; 21460d163575Sopenharmony_ci struct timeval stTimeVal; 21470d163575Sopenharmony_ci struct timeval deltaTimeVal; 21480d163575Sopenharmony_ci struct pbuf *pbuf_resp = NULL; 21490d163575Sopenharmony_ci struct pbuf *pbuf_req = NULL; 21500d163575Sopenharmony_ci int sfd = -1; 21510d163575Sopenharmony_ci u8_t type; 21520d163575Sopenharmony_ci u8_t select_on_socket = 0; 21530d163575Sopenharmony_ci char buf[INET6_ADDRSTRLEN]; 21540d163575Sopenharmony_ci 21550d163575Sopenharmony_ci if (!tcpip_init_finish) { 21560d163575Sopenharmony_ci PRINTK("%s: tcpip_init have not been called\n", __FUNCTION__); 21570d163575Sopenharmony_ci ret = -1; 21580d163575Sopenharmony_ci goto exit; 21590d163575Sopenharmony_ci } 21600d163575Sopenharmony_ci 21610d163575Sopenharmony_ci if ((argc < 1) || (argc > LWIP_MAX_PING6_ARG_COUNT) || (argv == NULL)) { 21620d163575Sopenharmony_ci goto usage; 21630d163575Sopenharmony_ci } 21640d163575Sopenharmony_ci 21650d163575Sopenharmony_ci ret = parse_args_ping6(argc, argv, &ping6_params); 21660d163575Sopenharmony_ci if (ret == -1) { 21670d163575Sopenharmony_ci goto exit; 21680d163575Sopenharmony_ci } 21690d163575Sopenharmony_ci 21700d163575Sopenharmony_ci if (ping6_params.args_found & LWIP_PING6_SOURCE_ADDRESS_ARG) { 21710d163575Sopenharmony_ci type = LWIP_PING6_SOURCE_ADDRESS_ARG; 21720d163575Sopenharmony_ci param = (void *)(&ping6_params.src_addr); 21730d163575Sopenharmony_ci } else if (ping6_params.args_found & LWIP_PING6_INTERFACE_ARG) { 21740d163575Sopenharmony_ci type = LWIP_PING6_INTERFACE_ARG; 21750d163575Sopenharmony_ci param = (void *)(argv[ping6_params.interface_index]); 21760d163575Sopenharmony_ci } else { 21770d163575Sopenharmony_ci type = LWIP_PING6_DEFAULT_SOCKET; 21780d163575Sopenharmony_ci param = NULL; 21790d163575Sopenharmony_ci } 21800d163575Sopenharmony_ci 21810d163575Sopenharmony_ci /* Create a socket for sending and receiving pings with appropriate bindings */ 21820d163575Sopenharmony_ci sfd = create_ping6_socket(type, param); 21830d163575Sopenharmony_ci if (sfd == -1) { 21840d163575Sopenharmony_ci ret = -1; 21850d163575Sopenharmony_ci goto exit; 21860d163575Sopenharmony_ci } 21870d163575Sopenharmony_ci 21880d163575Sopenharmony_ci pbuf_req = pbuf_alloc(PBUF_RAW, LWIP_PING6_STANDARD_PKT_SIZE, PBUF_RAM); 21890d163575Sopenharmony_ci pbuf_resp = pbuf_alloc(PBUF_RAW, LWIP_PING6_STANDARD_PKT_SIZE, PBUF_RAM); 21900d163575Sopenharmony_ci if ((pbuf_resp == NULL) || (pbuf_req == NULL)) { 21910d163575Sopenharmony_ci PRINTK("ping6 : Memory Allocation Failed\n"); 21920d163575Sopenharmony_ci ret = -1; 21930d163575Sopenharmony_ci goto exit; 21940d163575Sopenharmony_ci } 21950d163575Sopenharmony_ci 21960d163575Sopenharmony_ci to.sin6_family = AF_INET6; 21970d163575Sopenharmony_ci inet6_addr_from_ip6addr(&to.sin6_addr, &(ping6_params.dst_addr)); 21980d163575Sopenharmony_ci to.sin6_port = htons(IPPROTO_ICMPV6); 21990d163575Sopenharmony_ci 22000d163575Sopenharmony_ci#if LWIP_DNS 22010d163575Sopenharmony_ci if (lwip_strnicmp(inet_ntop(AF_INET6, &to.sin6_addr, buf, sizeof(buf)), argv[ping6_params.host_index], 22020d163575Sopenharmony_ci sizeof(to.sin6_addr))) { 22030d163575Sopenharmony_ci /* If There Was A DNS Resolution */ 22040d163575Sopenharmony_ci PRINTK("PING %s (%s) with %d bytes of data.\n", 22050d163575Sopenharmony_ci argv[ping6_params.host_index], buf, LWIP_PING6_STANDARD_PKT_SIZE); 22060d163575Sopenharmony_ci } else { 22070d163575Sopenharmony_ci PRINTK("PING %s with %d bytes of data.\n", buf, LWIP_PING6_STANDARD_PKT_SIZE); 22080d163575Sopenharmony_ci } 22090d163575Sopenharmony_ci#else 22100d163575Sopenharmony_ci PRINTK("PING %s with %d bytes of data\n", inet_ntop(AF_INET6, &to.sin6_addr, buf, sizeof(buf)), LWIP_PING6_STANDARD_PKT_SIZE); 22110d163575Sopenharmony_ci#endif /* LWIP_DNS */ 22120d163575Sopenharmony_ci 22130d163575Sopenharmony_ci nrecieve = 0; 22140d163575Sopenharmony_ci ping6_stats.flag = 0; 22150d163575Sopenharmony_ci ping6_stats.avg_rtt = 0; 22160d163575Sopenharmony_ci ping6_stats.max_rtt = 0; 22170d163575Sopenharmony_ci ping6_stats.min_rtt = 0; 22180d163575Sopenharmony_ci last_received = LWIP_PING6_STARTING_SEQ_NUM + LWIP_PING6_OUT_OF_ORDER_MAGNITUDE + 1; 22190d163575Sopenharmony_ci icmpv6_id = (u16_t)LWIP_RAND(); 22200d163575Sopenharmony_ci icmpv6_seq = LWIP_PING6_STARTING_SEQ_NUM; 22210d163575Sopenharmony_ci /* Setting the start time of the entire ping task for statistics */ 22220d163575Sopenharmony_ci (void)clock_gettime(CLOCK_MONOTONIC_RAW, &first); 22230d163575Sopenharmony_ci 22240d163575Sopenharmony_ci for (nsent = 0; nsent < ping6_params.pingcount; nsent++) { 22250d163575Sopenharmony_ci /* capture the start tick to calculate rtt */ 22260d163575Sopenharmony_ci (void)clock_gettime(CLOCK_MONOTONIC_RAW, &start); 22270d163575Sopenharmony_ci /* Initialize Memory To Prevent Uninitialized Memory Read Write Issues */ 22280d163575Sopenharmony_ci if (memset_s(pbuf_req->payload, pbuf_req->len, (int)(start.tv_nsec), pbuf_req->len) != 0) { 22290d163575Sopenharmony_ci goto exit; 22300d163575Sopenharmony_ci } 22310d163575Sopenharmony_ci 22320d163575Sopenharmony_ci iecho = (struct icmp6_echo_hdr *)pbuf_req->payload; 22330d163575Sopenharmony_ci iecho->type = ICMP6_TYPE_EREQ; 22340d163575Sopenharmony_ci iecho->id = icmpv6_id; 22350d163575Sopenharmony_ci icmpv6_seq++; 22360d163575Sopenharmony_ci iecho->seqno = icmpv6_seq; 22370d163575Sopenharmony_ci iecho->code = 0; 22380d163575Sopenharmony_ci 22390d163575Sopenharmony_ci /* Embedding the start_tick as data into the icmp_payload */ 22400d163575Sopenharmony_ci (void)pbuf_header(pbuf_req, (s16_t)(-(s16_t)(sizeof(struct icmp6_echo_hdr)))); 22410d163575Sopenharmony_ci if (memcpy_s(pbuf_req->payload, pbuf_req->len, (void *)&start, sizeof(start)) != 0) { 22420d163575Sopenharmony_ci goto exit; 22430d163575Sopenharmony_ci } 22440d163575Sopenharmony_ci (void)pbuf_header(pbuf_req, (s16_t)((s16_t)(sizeof(struct icmp6_echo_hdr)))); 22450d163575Sopenharmony_ci 22460d163575Sopenharmony_ci ret = lwip_sendto(sfd, iecho, pbuf_req->len, 0, (struct sockaddr *)&to, (socklen_t)sizeof(to)); 22470d163575Sopenharmony_ci if (ret == -1) { 22480d163575Sopenharmony_ci PRINTK("ping6 : Sending ICMP Echo message failed\n"); 22490d163575Sopenharmony_ci goto exit; 22500d163575Sopenharmony_ci } 22510d163575Sopenharmony_ci 22520d163575Sopenharmony_ci /* Wait in select for ICMP response msg */ 22530d163575Sopenharmony_ci FD_ZERO(&fdReadSet); 22540d163575Sopenharmony_ci FD_SET(sfd, &fdReadSet); 22550d163575Sopenharmony_ci stTimeVal.tv_sec = LWIP_MSECS_TO_SECS(LWIP_SHELL_CMD_PING_TIMEOUT); 22560d163575Sopenharmony_ci stTimeVal.tv_usec = 0; 22570d163575Sopenharmony_ci select_on_socket = 1; 22580d163575Sopenharmony_ci 22590d163575Sopenharmony_ci while (select_on_socket) { 22600d163575Sopenharmony_ci select_on_socket = 0; 22610d163575Sopenharmony_ci ret = select(sfd + 1, &fdReadSet, 0, 0, &stTimeVal); 22620d163575Sopenharmony_ci if (ret < 0) { 22630d163575Sopenharmony_ci PRINTK("ping6 : select failure\n"); 22640d163575Sopenharmony_ci goto exit; 22650d163575Sopenharmony_ci } else if (ret == 0) { 22660d163575Sopenharmony_ci (void)clock_gettime(CLOCK_MONOTONIC_RAW, &end); 22670d163575Sopenharmony_ci PRINTK("Request timed out\n"); 22680d163575Sopenharmony_ci continue; 22690d163575Sopenharmony_ci } 22700d163575Sopenharmony_ci 22710d163575Sopenharmony_ci /* capture the end time to calculate round trip time */ 22720d163575Sopenharmony_ci (void)clock_gettime(CLOCK_MONOTONIC_RAW, &end); 22730d163575Sopenharmony_ci 22740d163575Sopenharmony_ci ret = lwip_recv(sfd, pbuf_resp->payload, pbuf_resp->len, 0); 22750d163575Sopenharmony_ci if (ret == -1) { 22760d163575Sopenharmony_ci PRINTK("ping6 : receiving ICMP echo response msg failed\n"); 22770d163575Sopenharmony_ci goto exit; 22780d163575Sopenharmony_ci } 22790d163575Sopenharmony_ci 22800d163575Sopenharmony_ci if ((u32_t)ret < sizeof(struct icmp6_echo_hdr *)) { 22810d163575Sopenharmony_ci /* Drop the packet if its too short [Doesn't contain even the header !!] */ 22820d163575Sopenharmony_ci PRINTK("ping6 : received ICMP echo response too short\n"); 22830d163575Sopenharmony_ci goto REDUCE_SELECT_TIME; 22840d163575Sopenharmony_ci } 22850d163575Sopenharmony_ci 22860d163575Sopenharmony_ci /* Acceping the ICMPv6 payload. */ 22870d163575Sopenharmony_ci /* Here, pbuf_resp->payload won't contain IPv6 Header since its an AF_INET6 RAW Socket */ 22880d163575Sopenharmony_ci iecho_resp = (struct icmp6_echo_hdr *)pbuf_resp->payload; 22890d163575Sopenharmony_ci 22900d163575Sopenharmony_ci if (iecho_resp->id == icmpv6_id) { 22910d163575Sopenharmony_ci if (iecho_resp->type == ICMP6_TYPE_EREP) { 22920d163575Sopenharmony_ci if (ret < LWIP_PING6_STANDARD_PKT_SIZE) { 22930d163575Sopenharmony_ci /* Drop the packet if its too short */ 22940d163575Sopenharmony_ci PRINTK("ping6 : received ICMP echo response too short\n"); 22950d163575Sopenharmony_ci goto REDUCE_SELECT_TIME; 22960d163575Sopenharmony_ci } 22970d163575Sopenharmony_ci /* Accept and process only those delayed EREP only if its sequence num is within out-of-order magnitude */ 22980d163575Sopenharmony_ci if (nsent && iecho_resp->seqno != icmpv6_seq && 22990d163575Sopenharmony_ci (iecho_resp->seqno<(u16_t)(last_received - LWIP_PING6_OUT_OF_ORDER_MAGNITUDE) || 23000d163575Sopenharmony_ci iecho_resp->seqno>(u16_t)( 23010d163575Sopenharmony_ci last_received + LWIP_PING6_OUT_OF_ORDER_MAGNITUDE))) { 23020d163575Sopenharmony_ci /* Otherwise drop it and wait for more packets */ 23030d163575Sopenharmony_ci goto REDUCE_SELECT_TIME; 23040d163575Sopenharmony_ci } 23050d163575Sopenharmony_ci ++nrecieve; 23060d163575Sopenharmony_ci last_received = iecho_resp->seqno; 23070d163575Sopenharmony_ci /* Retrieving the start_tick from the packet which was embedded when the request was transmitted */ 23080d163575Sopenharmony_ci (void)pbuf_header(pbuf_resp, (s16_t)(-(s16_t)(sizeof(struct icmp6_echo_hdr)))); 23090d163575Sopenharmony_ci if (memcpy_s((void *)&start_in_reply, sizeof(start_in_reply), 23100d163575Sopenharmony_ci pbuf_resp->payload, sizeof(start_in_reply)) != EOK) { 23110d163575Sopenharmony_ci goto REDUCE_SELECT_TIME; 23120d163575Sopenharmony_ci } 23130d163575Sopenharmony_ci (void)pbuf_header(pbuf_resp, (s16_t)((s16_t)(sizeof(struct icmp6_echo_hdr)))); 23140d163575Sopenharmony_ci 23150d163575Sopenharmony_ci rtt = ((end.tv_sec - start.tv_sec) * 1000 + (end.tv_nsec - start.tv_nsec) / 1000000); 23160d163575Sopenharmony_ci 23170d163575Sopenharmony_ci PRINTK("%d bytes from %s : icmp_seq=%d time", ret, 23180d163575Sopenharmony_ci inet_ntop(AF_INET6, &to.sin6_addr, buf, sizeof(buf)), 23190d163575Sopenharmony_ci ((iecho_resp->seqno) - LWIP_PING6_STARTING_SEQ_NUM)); 23200d163575Sopenharmony_ci if (rtt < 1) { 23210d163575Sopenharmony_ci PRINTK("<1 ms\n"); 23220d163575Sopenharmony_ci } else { 23230d163575Sopenharmony_ci PRINTK("=%i ms\n", rtt); 23240d163575Sopenharmony_ci } 23250d163575Sopenharmony_ci 23260d163575Sopenharmony_ci update_ping6_stats(&ping6_stats, (u32_t)(rtt), nrecieve); 23270d163575Sopenharmony_ci 23280d163575Sopenharmony_ci /* Checking if its a delayed packet */ 23290d163575Sopenharmony_ci if ((iecho_resp->seqno != icmpv6_seq) && (nsent < ping6_params.pingcount)) { 23300d163575Sopenharmony_ci /* In case of delayed packet wait on socket for other response before sending a new PING */ 23310d163575Sopenharmony_ci /* We have to reduce the timeout value now when selecting on socket */ 23320d163575Sopenharmony_ci goto REDUCE_SELECT_TIME; 23330d163575Sopenharmony_ci } 23340d163575Sopenharmony_ci } else { 23350d163575Sopenharmony_ci PRINTK("[%u]ping6 : %s\n", nsent, convert_icmpv6_err_to_string(iecho_resp->type)); 23360d163575Sopenharmony_ci } 23370d163575Sopenharmony_ci } else { 23380d163575Sopenharmony_ci /* If incoming packet does not matches with icmp_id, it should be ignored */ 23390d163575Sopenharmony_ci /* Reduce the timeout for select on socket */ 23400d163575Sopenharmony_ciREDUCE_SELECT_TIME: 23410d163575Sopenharmony_ci deltaTimeVal.tv_sec = (long)(end.tv_sec - start.tv_sec); 23420d163575Sopenharmony_ci deltaTimeVal.tv_usec = (long)((end.tv_nsec - start.tv_nsec) / 1000); 23430d163575Sopenharmony_ci /* Subtract deltaTime from stTime and store in stTime */ 23440d163575Sopenharmony_ci /* This will reduce the select time on the socket */ 23450d163575Sopenharmony_ci timersub(&stTimeVal, &deltaTimeVal, &stTimeVal); 23460d163575Sopenharmony_ci select_on_socket = 1; 23470d163575Sopenharmony_ci } 23480d163575Sopenharmony_ci } 23490d163575Sopenharmony_ci } 23500d163575Sopenharmony_ci 23510d163575Sopenharmony_ci ret = ERR_OK; 23520d163575Sopenharmony_ci 23530d163575Sopenharmony_ci (void)clock_gettime(CLOCK_MONOTONIC_RAW, &last); 23540d163575Sopenharmony_ci /* Display ping stats */ 23550d163575Sopenharmony_ci PRINTK("--- %s ping statistics ---\n", argv[ping6_params.host_index]); 23560d163575Sopenharmony_ci PRINTK("%d packets transmitted, %d received, %.2f%% packet loss, time %dms\n", 23570d163575Sopenharmony_ci nsent, nrecieve, (float)(((float)(nsent - nrecieve)) * ((float)(100)) / ((float)(nsent))), 23580d163575Sopenharmony_ci /* 1000: convert seconds to milliseconds, 1000000: convert nanoseconds to milliseconds */ 23590d163575Sopenharmony_ci ((last.tv_sec - first.tv_sec) * 1000 + (last.tv_nsec - first.tv_nsec) / 1000000)); 23600d163575Sopenharmony_ci if (nrecieve) { 23610d163575Sopenharmony_ci /* Display rtt stats only if at least one packet is received */ 23620d163575Sopenharmony_ci PRINTK("rtt min/avg/max = %u/%.2f/%u ms\n", ping6_stats.min_rtt, ping6_stats.avg_rtt, ping6_stats.max_rtt); 23630d163575Sopenharmony_ci } 23640d163575Sopenharmony_ci 23650d163575Sopenharmony_ciexit: 23660d163575Sopenharmony_ci if (sfd != -1) { 23670d163575Sopenharmony_ci (void)lwip_close(sfd); 23680d163575Sopenharmony_ci } 23690d163575Sopenharmony_ci 23700d163575Sopenharmony_ci if (pbuf_resp != NULL) { 23710d163575Sopenharmony_ci (void)pbuf_free(pbuf_resp); 23720d163575Sopenharmony_ci } 23730d163575Sopenharmony_ci 23740d163575Sopenharmony_ci if (pbuf_req != NULL) { 23750d163575Sopenharmony_ci (void)pbuf_free(pbuf_req); 23760d163575Sopenharmony_ci } 23770d163575Sopenharmony_ci return (u32_t)((ret == (int)ERR_OK) ? LOS_OK : LOS_NOK); 23780d163575Sopenharmony_ci 23790d163575Sopenharmony_ciusage: 23800d163575Sopenharmony_ci PRINTK("Usage:\n"); 23810d163575Sopenharmony_ci PRINTK("\tping6 [-c count] [-I interface/sourceAddress] destination\n"); 23820d163575Sopenharmony_ci return LOS_NOK; 23830d163575Sopenharmony_ci} 23840d163575Sopenharmony_ci 23850d163575Sopenharmony_ciLWIP_STATIC int create_ping6_socket(u8_t type, const void *param) 23860d163575Sopenharmony_ci{ 23870d163575Sopenharmony_ci int sfd; 23880d163575Sopenharmony_ci int ret; 23890d163575Sopenharmony_ci struct sockaddr_in6 stHostAddr6; 23900d163575Sopenharmony_ci struct icmp6_filter icmp6_sock_filter; 23910d163575Sopenharmony_ci 23920d163575Sopenharmony_ci sfd = lwip_socket(PF_INET6, SOCK_RAW, IPPROTO_ICMPV6); 23930d163575Sopenharmony_ci if (sfd == -1) { 23940d163575Sopenharmony_ci PRINTK("ping6 : Failed, socket creation failed\n"); 23950d163575Sopenharmony_ci return -1; 23960d163575Sopenharmony_ci } 23970d163575Sopenharmony_ci 23980d163575Sopenharmony_ci if (param != NULL) { 23990d163575Sopenharmony_ci if (type == LWIP_PING6_SOURCE_ADDRESS_ARG) { 24000d163575Sopenharmony_ci /* Binding socket to the provided source address */ 24010d163575Sopenharmony_ci (void)memset_s(&stHostAddr6, sizeof(stHostAddr6), 0, sizeof(stHostAddr6)); 24020d163575Sopenharmony_ci stHostAddr6.sin6_family = AF_INET6; 24030d163575Sopenharmony_ci inet6_addr_from_ip6addr(&stHostAddr6.sin6_addr, (ip6_addr_t *)param); 24040d163575Sopenharmony_ci stHostAddr6.sin6_port = htons(IPPROTO_ICMPV6); 24050d163575Sopenharmony_ci stHostAddr6.sin6_scope_id = 0; 24060d163575Sopenharmony_ci 24070d163575Sopenharmony_ci ret = lwip_bind(sfd, (struct sockaddr *)&stHostAddr6, sizeof(stHostAddr6)); 24080d163575Sopenharmony_ci if (ret == -1) { 24090d163575Sopenharmony_ci (void)lwip_close(sfd); 24100d163575Sopenharmony_ci PRINTK("ping6 : bind icmp socket: cannot assign requested address\n"); 24110d163575Sopenharmony_ci return ret; 24120d163575Sopenharmony_ci } 24130d163575Sopenharmony_ci } else if (type == LWIP_PING6_INTERFACE_ARG) { 24140d163575Sopenharmony_ci /* Binding socket to the provided netif */ 24150d163575Sopenharmony_ci ret = lwip_setsockopt(sfd, SOL_SOCKET, SO_BINDTODEVICE, (char *)(param), strlen((char *)(param))); 24160d163575Sopenharmony_ci if (ret == -1) { 24170d163575Sopenharmony_ci (void)lwip_close(sfd); 24180d163575Sopenharmony_ci PRINTK("ping6: unknownn iface %s\n", (char *)(param)); 24190d163575Sopenharmony_ci return ret; 24200d163575Sopenharmony_ci } 24210d163575Sopenharmony_ci } 24220d163575Sopenharmony_ci } 24230d163575Sopenharmony_ci 24240d163575Sopenharmony_ci /* Setting socket filter since we are interested only in ECHO REPLY and ERROR messages */ 24250d163575Sopenharmony_ci ICMP6_FILTER_SETBLOCKALL(&icmp6_sock_filter); 24260d163575Sopenharmony_ci ICMP6_FILTER_SETPASS(ICMP6_TYPE_EREP, &icmp6_sock_filter); 24270d163575Sopenharmony_ci ICMP6_FILTER_SETPASS(ICMP6_TYPE_DUR, &icmp6_sock_filter); 24280d163575Sopenharmony_ci ICMP6_FILTER_SETPASS(ICMP6_TYPE_PTB, &icmp6_sock_filter); 24290d163575Sopenharmony_ci ICMP6_FILTER_SETPASS(ICMP6_TYPE_TE, &icmp6_sock_filter); 24300d163575Sopenharmony_ci 24310d163575Sopenharmony_ci ret = lwip_setsockopt(sfd, IPPROTO_ICMPV6, ICMP6_FILTER, &icmp6_sock_filter, sizeof(struct icmp6_filter)); 24320d163575Sopenharmony_ci if (ret == -1) { 24330d163575Sopenharmony_ci (void)lwip_close(sfd); 24340d163575Sopenharmony_ci PRINTK("ping6 : setsockopt: Invalid Argument\n"); 24350d163575Sopenharmony_ci return -1; 24360d163575Sopenharmony_ci } 24370d163575Sopenharmony_ci 24380d163575Sopenharmony_ci return sfd; 24390d163575Sopenharmony_ci} 24400d163575Sopenharmony_ci 24410d163575Sopenharmony_ci/* 24420d163575Sopenharmony_ci * Function to parse the command line args for ping6 shell utility 24430d163575Sopenharmony_ci * @return: 24440d163575Sopenharmony_ci * Success: ERR_OK 24450d163575Sopenharmony_ci * Failure: -1 24460d163575Sopenharmony_ci */ 24470d163575Sopenharmony_ciLWIP_STATIC int parse_args_ping6(int argc, const char **argv, ping6_args_t *ping6_params) 24480d163575Sopenharmony_ci{ 24490d163575Sopenharmony_ci int pingcount; 24500d163575Sopenharmony_ci int ret = -1; 24510d163575Sopenharmony_ci#if LWIP_DNS 24520d163575Sopenharmony_ci struct addrinfo *res = NULL; 24530d163575Sopenharmony_ci struct addrinfo hints_structure; 24540d163575Sopenharmony_ci#endif 24550d163575Sopenharmony_ci u8_t i = 0; 24560d163575Sopenharmony_ci 24570d163575Sopenharmony_ci IP6_ADDR(&(ping6_params->dst_addr), 0, 0, 0, 0); 24580d163575Sopenharmony_ci IP6_ADDR(&(ping6_params->src_addr), 0, 0, 0, 0); 24590d163575Sopenharmony_ci 24600d163575Sopenharmony_ci ping6_params->pingcount = LWIP_SHELL_CMD_PING_RETRY_TIMES; 24610d163575Sopenharmony_ci ping6_params->host_index = 0; 24620d163575Sopenharmony_ci ping6_params->args_found = 0; 24630d163575Sopenharmony_ci 24640d163575Sopenharmony_ci while (i < argc) { 24650d163575Sopenharmony_ci if (strcmp("-c", argv[i]) == 0) { 24660d163575Sopenharmony_ci /* Handle number of ICMP packets to transmit :: -c [number_of_packets] */ 24670d163575Sopenharmony_ci if (ping6_params->args_found & LWIP_PING6_COUNT_ARG) { 24680d163575Sopenharmony_ci PRINTK("ping6: -c option present multiple times \n"); 24690d163575Sopenharmony_ci ret = -1; 24700d163575Sopenharmony_ci goto exit; 24710d163575Sopenharmony_ci } 24720d163575Sopenharmony_ci 24730d163575Sopenharmony_ci if (i + 2 > argc) { 24740d163575Sopenharmony_ci PRINTK("ping6: ping count(-c) should require an argument \n"); 24750d163575Sopenharmony_ci ret = -1; 24760d163575Sopenharmony_ci goto exit; 24770d163575Sopenharmony_ci } 24780d163575Sopenharmony_ci 24790d163575Sopenharmony_ci pingcount = atoi(argv[i + 1]); 24800d163575Sopenharmony_ci if (pingcount <= 0) { 24810d163575Sopenharmony_ci PRINTK("ping6: bad number of packets to transmit \n"); 24820d163575Sopenharmony_ci ret = -1; 24830d163575Sopenharmony_ci goto exit; 24840d163575Sopenharmony_ci } 24850d163575Sopenharmony_ci 24860d163575Sopenharmony_ci ping6_params->args_found |= LWIP_PING6_COUNT_ARG; 24870d163575Sopenharmony_ci ping6_params->pingcount = (u32_t)pingcount; 24880d163575Sopenharmony_ci i = (u8_t)(i + 2); 24890d163575Sopenharmony_ci } else if (strcmp("-I", argv[i]) == 0) { 24900d163575Sopenharmony_ci /* Handle interface ID / sourceAddress using which the ICMP Packets has to be transmitted :: -I [interface_id/source_address] */ 24910d163575Sopenharmony_ci 24920d163575Sopenharmony_ci if ((ping6_params->args_found & LWIP_PING6_SOURCE_ADDRESS_ARG) || 24930d163575Sopenharmony_ci (ping6_params->args_found & LWIP_PING6_INTERFACE_ARG)) { 24940d163575Sopenharmony_ci PRINTK("ping6: -I option present multiple times \n"); 24950d163575Sopenharmony_ci ret = -1; 24960d163575Sopenharmony_ci goto exit; 24970d163575Sopenharmony_ci } 24980d163575Sopenharmony_ci 24990d163575Sopenharmony_ci if (i + 2 > argc) { 25000d163575Sopenharmony_ci PRINTK("ping6: interface/source address(-I) should require an argument \n"); 25010d163575Sopenharmony_ci ret = -1; 25020d163575Sopenharmony_ci goto exit; 25030d163575Sopenharmony_ci } 25040d163575Sopenharmony_ci 25050d163575Sopenharmony_ci /* Check whether the given argument to -I is source address */ 25060d163575Sopenharmony_ci if (ip6addr_aton(argv[i + 1], &(ping6_params->src_addr))) { 25070d163575Sopenharmony_ci ping6_params->args_found |= LWIP_PING6_SOURCE_ADDRESS_ARG; 25080d163575Sopenharmony_ci i = (u8_t)(i + 2); 25090d163575Sopenharmony_ci continue; 25100d163575Sopenharmony_ci } 25110d163575Sopenharmony_ci 25120d163575Sopenharmony_ci /* Storing the index where interface name is found */ 25130d163575Sopenharmony_ci /* If this name is not valid, then it will fail later in setsockopt(BIND_TO_DEVICE) */ 25140d163575Sopenharmony_ci ping6_params->interface_index = (u8_t)(i + 1); 25150d163575Sopenharmony_ci ping6_params->args_found |= LWIP_PING6_INTERFACE_ARG; 25160d163575Sopenharmony_ci 25170d163575Sopenharmony_ci i = (u8_t)(i + 2); 25180d163575Sopenharmony_ci } else { 25190d163575Sopenharmony_ci if (argv[i][0] == '-') { 25200d163575Sopenharmony_ci /* Check whether its a bad option */ 25210d163575Sopenharmony_ci PRINTK("ping6: bad option %s\n", argv[i]); 25220d163575Sopenharmony_ci ret = -1; 25230d163575Sopenharmony_ci goto exit; 25240d163575Sopenharmony_ci } else if (ping6_params->args_found & LWIP_PING6_HOSTNAME_ARG) { 25250d163575Sopenharmony_ci /* Check whether hostname is already found and there are extra arguments */ 25260d163575Sopenharmony_ci PRINTK("ping6: bad parameter %s\n", argv[i]); 25270d163575Sopenharmony_ci ret = -1; 25280d163575Sopenharmony_ci goto exit; 25290d163575Sopenharmony_ci } 25300d163575Sopenharmony_ci 25310d163575Sopenharmony_ci#if LWIP_DNS 25320d163575Sopenharmony_ci /* Resolve the given hostname */ 25330d163575Sopenharmony_ci hints_structure.ai_family = AF_INET6; 25340d163575Sopenharmony_ci hints_structure.ai_flags = 0; 25350d163575Sopenharmony_ci ret = lwip_getaddrinfo(argv[i], NULL, &hints_structure, &res); 25360d163575Sopenharmony_ci if (ret != ERR_OK) { 25370d163575Sopenharmony_ci PRINTK("ping6 : Host : %s can't be resolved to IPv6 address\n", argv[i]); 25380d163575Sopenharmony_ci ret = -1; 25390d163575Sopenharmony_ci goto exit; 25400d163575Sopenharmony_ci } 25410d163575Sopenharmony_ci 25420d163575Sopenharmony_ci inet6_addr_to_ip6addr(&(ping6_params->dst_addr), 25430d163575Sopenharmony_ci &(((const struct sockaddr_in6 *)(res->ai_addr))->sin6_addr)); 25440d163575Sopenharmony_ci#else 25450d163575Sopenharmony_ci /* Convert the string representation to network form */ 25460d163575Sopenharmony_ci if (!ip6addr_aton(argv[i], &(ping6_params->dst_addr))) { 25470d163575Sopenharmony_ci PRINTK("ping6 : Invalid IPv6 Address : %s\n", argv[i]); 25480d163575Sopenharmony_ci ret = -1; 25490d163575Sopenharmony_ci goto exit; 25500d163575Sopenharmony_ci } 25510d163575Sopenharmony_ci#endif /* LWIP_DNS */ 25520d163575Sopenharmony_ci if (ip6_addr_isany(&(ping6_params->dst_addr)) || ip6_addr_isnone(&(ping6_params->dst_addr))) { 25530d163575Sopenharmony_ci#if LWIP_DNS 25540d163575Sopenharmony_ci PRINTK("ping6 : IPv6 address of host : %s (%s) is invalid\n", argv[i], 25550d163575Sopenharmony_ci ip6addr_ntoa((const ip6_addr_t *)&(ping6_params->dst_addr))); 25560d163575Sopenharmony_ci#else 25570d163575Sopenharmony_ci PRINTK("ping6 : Invalid IPv6 address : %s\n", argv[i]); 25580d163575Sopenharmony_ci#endif /* LWIP_DNS */ 25590d163575Sopenharmony_ci goto exit; 25600d163575Sopenharmony_ci } 25610d163575Sopenharmony_ci /* Setting host_index to the index of argv[] where the host/IP is present */ 25620d163575Sopenharmony_ci ping6_params->args_found |= LWIP_PING6_HOSTNAME_ARG; 25630d163575Sopenharmony_ci ping6_params->host_index = (u8_t)(i); 25640d163575Sopenharmony_ci i = (u8_t)(i + 1); 25650d163575Sopenharmony_ci } 25660d163575Sopenharmony_ci } 25670d163575Sopenharmony_ci 25680d163575Sopenharmony_ci if (!(ping6_params->args_found & LWIP_PING6_HOSTNAME_ARG)) { 25690d163575Sopenharmony_ci /* Hostname/IPv6 address not found */ 25700d163575Sopenharmony_ci PRINTK("ping6 : Hostname/IPv6 address to ping is not specified\n"); 25710d163575Sopenharmony_ci ret = -1; 25720d163575Sopenharmony_ci goto exit; 25730d163575Sopenharmony_ci } 25740d163575Sopenharmony_ci 25750d163575Sopenharmony_ci if (ip6_addr_islinklocal(&(ping6_params->dst_addr)) && 25760d163575Sopenharmony_ci !(ping6_params->args_found & (LWIP_PING6_INTERFACE_ARG | LWIP_PING6_SOURCE_ADDRESS_ARG))) { 25770d163575Sopenharmony_ci /* For link-local addresses, -I is mandatory */ 25780d163575Sopenharmony_ci PRINTK("ping6 : Interface specification is mandatory for link-local addresses\n"); 25790d163575Sopenharmony_ci ret = -1; 25800d163575Sopenharmony_ci goto exit; 25810d163575Sopenharmony_ci } 25820d163575Sopenharmony_ci 25830d163575Sopenharmony_ci ret = ERR_OK; 25840d163575Sopenharmony_ci 25850d163575Sopenharmony_ciexit: 25860d163575Sopenharmony_ci#if LWIP_DNS 25870d163575Sopenharmony_ci lwip_freeaddrinfo(res); 25880d163575Sopenharmony_ci#endif /* LWIP_DNS */ 25890d163575Sopenharmony_ci 25900d163575Sopenharmony_ci return ret; 25910d163575Sopenharmony_ci} 25920d163575Sopenharmony_ci 25930d163575Sopenharmony_ci/* 25940d163575Sopenharmony_ci * Function to update ping6_stats 25950d163575Sopenharmony_ci * stats is maintained in ping6_stats structure 25960d163575Sopenharmony_ci */ 25970d163575Sopenharmony_ciLWIP_STATIC void update_ping6_stats(ping6_stats_t *ping6_stats, u32_t rtt, u32_t nreceived) 25980d163575Sopenharmony_ci{ 25990d163575Sopenharmony_ci if (rtt > ping6_stats->max_rtt) { 26000d163575Sopenharmony_ci ping6_stats->max_rtt = rtt; 26010d163575Sopenharmony_ci } 26020d163575Sopenharmony_ci 26030d163575Sopenharmony_ci if (ping6_stats->flag == 0 || rtt < ping6_stats->min_rtt) { 26040d163575Sopenharmony_ci ping6_stats->min_rtt = rtt; 26050d163575Sopenharmony_ci ping6_stats->flag = 1; 26060d163575Sopenharmony_ci } 26070d163575Sopenharmony_ci 26080d163575Sopenharmony_ci ping6_stats->avg_rtt = (float)(ping6_stats->avg_rtt + 26090d163575Sopenharmony_ci (float)((float)((float)rtt - ping6_stats->avg_rtt) / (float)(nreceived))); 26100d163575Sopenharmony_ci} 26110d163575Sopenharmony_ci 26120d163575Sopenharmony_ciLWIP_STATIC const char *convert_icmpv6_err_to_string(u8_t err_type) 26130d163575Sopenharmony_ci{ 26140d163575Sopenharmony_ci switch (err_type) { 26150d163575Sopenharmony_ci case ICMP6_TYPE_DUR: 26160d163575Sopenharmony_ci return "Destination Unreachable"; 26170d163575Sopenharmony_ci case ICMP6_TYPE_PTB: 26180d163575Sopenharmony_ci return "Packet too big"; 26190d163575Sopenharmony_ci case ICMP6_TYPE_TE: 26200d163575Sopenharmony_ci return "Time Exceeded"; 26210d163575Sopenharmony_ci case ICMP6_TYPE_PP: 26220d163575Sopenharmony_ci return "Parameter Problem"; 26230d163575Sopenharmony_ci default: 26240d163575Sopenharmony_ci break; 26250d163575Sopenharmony_ci } 26260d163575Sopenharmony_ci return "Unknown Error"; 26270d163575Sopenharmony_ci} 26280d163575Sopenharmony_ci 26290d163575Sopenharmony_ci#ifdef LOSCFG_SHELL_CMD_DEBUG 26300d163575Sopenharmony_ciSHELLCMD_ENTRY(ping6_shellcmd, CMD_TYPE_EX, "ping6", XARGS, (CmdCallBackFunc)osShellPing6); 26310d163575Sopenharmony_ci#endif /* LOSCFG_SHELL_CMD_DEBUG */ 26320d163575Sopenharmony_ci#endif /* LWIP_IPV6 */ 26330d163575Sopenharmony_ci 26340d163575Sopenharmony_ci#if LWIP_SNTP 26350d163575Sopenharmony_ciu32_t osShellNtpdate(int argc, const char **argv) 26360d163575Sopenharmony_ci{ 26370d163575Sopenharmony_ci int server_num = 0; 26380d163575Sopenharmony_ci char *ret = NULL; 26390d163575Sopenharmony_ci struct timeval get_time; 26400d163575Sopenharmony_ci char buf[50]; 26410d163575Sopenharmony_ci 26420d163575Sopenharmony_ci (void)memset_s(&get_time, sizeof(struct timeval), 0, sizeof(struct timeval)); 26430d163575Sopenharmony_ci 26440d163575Sopenharmony_ci if (!tcpip_init_finish) { 26450d163575Sopenharmony_ci PRINTK("%s: tcpip_init have not been called\n", __FUNCTION__); 26460d163575Sopenharmony_ci return LOS_NOK; 26470d163575Sopenharmony_ci } 26480d163575Sopenharmony_ci 26490d163575Sopenharmony_ci if (argc < 1 || argv == NULL) { 26500d163575Sopenharmony_ci goto usage; 26510d163575Sopenharmony_ci } 26520d163575Sopenharmony_ci 26530d163575Sopenharmony_ci server_num = lwip_sntp_start(argc, (char **)argv, &get_time); 26540d163575Sopenharmony_ci if (server_num >= 0 && server_num < argc) { 26550d163575Sopenharmony_ci ret = ctime_r((time_t *)&get_time.tv_sec, buf); 26560d163575Sopenharmony_ci if (ret != NULL) { 26570d163575Sopenharmony_ci PRINTK("time server %s: %s\n", argv[server_num], ret); 26580d163575Sopenharmony_ci } else { 26590d163575Sopenharmony_ci PRINTK("ctime return null error\n"); 26600d163575Sopenharmony_ci } 26610d163575Sopenharmony_ci } else { 26620d163575Sopenharmony_ci PRINTK("no server suitable for synchronization found\n"); 26630d163575Sopenharmony_ci } 26640d163575Sopenharmony_ci 26650d163575Sopenharmony_ci return LOS_OK; 26660d163575Sopenharmony_ci 26670d163575Sopenharmony_ciusage: 26680d163575Sopenharmony_ci PRINTK("\nUsage:\n"); 26690d163575Sopenharmony_ci PRINTK("ntpdate [SERVER_IP1] [SERVER_IP2] ...\n"); 26700d163575Sopenharmony_ci return LOS_NOK; 26710d163575Sopenharmony_ci} 26720d163575Sopenharmony_ci 26730d163575Sopenharmony_ci#ifdef LOSCFG_SHELL_CMD_DEBUG 26740d163575Sopenharmony_ciSHELLCMD_ENTRY(ntpdate_shellcmd, CMD_TYPE_EX, "ntpdate", XARGS, (CmdCallBackFunc)osShellNtpdate); 26750d163575Sopenharmony_ci#endif /* LOSCFG_SHELL_CMD_DEBUG */ 26760d163575Sopenharmony_ci 26770d163575Sopenharmony_ci#endif /* LWIP_SNTP */ 26780d163575Sopenharmony_ci 26790d163575Sopenharmony_ci#if LWIP_DNS 26800d163575Sopenharmony_ciu32_t osShellDns(int argc, const char **argv) 26810d163575Sopenharmony_ci{ 26820d163575Sopenharmony_ci ip_addr_t dns = {0}; 26830d163575Sopenharmony_ci err_t err; 26840d163575Sopenharmony_ci int i; 26850d163575Sopenharmony_ci if (argc < 1 || argv == NULL) { 26860d163575Sopenharmony_ci goto usage; 26870d163575Sopenharmony_ci } 26880d163575Sopenharmony_ci 26890d163575Sopenharmony_ci if (tcpip_init_finish == 0) { 26900d163575Sopenharmony_ci PRINTK("%s: tcpip_init have not been called\n", __FUNCTION__); 26910d163575Sopenharmony_ci return LOS_NOK; 26920d163575Sopenharmony_ci } 26930d163575Sopenharmony_ci 26940d163575Sopenharmony_ci if (argc == 1 && (strcmp(argv[0], "-a") == 0)) { 26950d163575Sopenharmony_ci for (i = 0; i < DNS_MAX_SERVERS; i++) { 26960d163575Sopenharmony_ci err = lwip_dns_getserver((u8_t)i, &dns); 26970d163575Sopenharmony_ci if (err == ERR_OK) { 26980d163575Sopenharmony_ci PRINTK("dns %d: %s\n", i + 1, ipaddr_ntoa_unsafe(&dns)); 26990d163575Sopenharmony_ci } else { 27000d163575Sopenharmony_ci PRINTK("dns: failed\n"); 27010d163575Sopenharmony_ci return LOS_NOK; 27020d163575Sopenharmony_ci } 27030d163575Sopenharmony_ci } 27040d163575Sopenharmony_ci return LOS_OK; 27050d163575Sopenharmony_ci } else if (argc == 2) { 27060d163575Sopenharmony_ci i = atoi(argv[0]); 27070d163575Sopenharmony_ci if ((i <= 0) || (i > DNS_MAX_SERVERS)) 27080d163575Sopenharmony_ci goto usage; 27090d163575Sopenharmony_ci#if LWIP_IPV6 27100d163575Sopenharmony_ci if (ip6addr_aton(argv[1], ((ip6_addr_t *)&dns))) { 27110d163575Sopenharmony_ci#if LWIP_IPV4 && LWIP_IPV6 27120d163575Sopenharmony_ci dns.type = IPADDR_TYPE_V6; 27130d163575Sopenharmony_ci#endif 27140d163575Sopenharmony_ci if (!ip6_addr_isglobal((ip6_addr_t *)&dns)) { 27150d163575Sopenharmony_ci PRINTK("ip address<%s> is wrong\n", argv[1]); 27160d163575Sopenharmony_ci return LOS_NOK; 27170d163575Sopenharmony_ci } 27180d163575Sopenharmony_ci } else 27190d163575Sopenharmony_ci#endif 27200d163575Sopenharmony_ci { 27210d163575Sopenharmony_ci#if LWIP_IPV4 27220d163575Sopenharmony_ci ((ip4_addr_t *)&dns)->addr = ipaddr_addr(argv[1]); 27230d163575Sopenharmony_ci if (((ip4_addr_t *)&dns)->addr == IPADDR_NONE) { 27240d163575Sopenharmony_ci PRINTK("ip address<%s> is wrong\n", argv[1]); 27250d163575Sopenharmony_ci return LOS_NOK; 27260d163575Sopenharmony_ci } 27270d163575Sopenharmony_ci#if LWIP_IPV4 && LWIP_IPV6 27280d163575Sopenharmony_ci dns.type = IPADDR_TYPE_V4; 27290d163575Sopenharmony_ci#endif 27300d163575Sopenharmony_ci#endif 27310d163575Sopenharmony_ci } 27320d163575Sopenharmony_ci 27330d163575Sopenharmony_ci err = lwip_dns_setserver((u8_t)(i - 1), &dns); 27340d163575Sopenharmony_ci if (err != ERR_OK) { 27350d163575Sopenharmony_ci PRINTK("dns : failed\n"); 27360d163575Sopenharmony_ci return LOS_NOK; 27370d163575Sopenharmony_ci } 27380d163575Sopenharmony_ci return LOS_OK; 27390d163575Sopenharmony_ci } 27400d163575Sopenharmony_ciusage: 27410d163575Sopenharmony_ci PRINTK("usage:\n"); 27420d163575Sopenharmony_ci PRINTK("\tdns <1-%d> <IP>\n", DNS_MAX_SERVERS); 27430d163575Sopenharmony_ci PRINTK("\tdns -a\n"); 27440d163575Sopenharmony_ci return LOS_NOK; 27450d163575Sopenharmony_ci} 27460d163575Sopenharmony_ci 27470d163575Sopenharmony_ci#ifdef LOSCFG_SHELL_CMD_DEBUG 27480d163575Sopenharmony_ciSHELLCMD_ENTRY(dns_shellcmd, CMD_TYPE_EX, "dns", XARGS, (CmdCallBackFunc)osShellDns); 27490d163575Sopenharmony_ci#endif /* LOSCFG_SHELL_CMD_DEBUG */ 27500d163575Sopenharmony_ci#endif /* LWIP_DNS */ 27510d163575Sopenharmony_ci#if LWIP_IPV6 27520d163575Sopenharmony_ciextern struct nd6_neighbor_cache_entry neighbor_cache[LWIP_ND6_NUM_NEIGHBORS]; 27530d163575Sopenharmony_ci#endif 27540d163575Sopenharmony_ci#if LWIP_IPV6 27550d163575Sopenharmony_ciint netstat_get_udp_sendQLen6(struct udp_pcb *udppcb, struct pbuf *udpbuf) 27560d163575Sopenharmony_ci{ 27570d163575Sopenharmony_ci int sendLen = -1; 27580d163575Sopenharmony_ci u16_t offset = 0, len; 27590d163575Sopenharmony_ci struct ip6_hdr *iphdr = NULL; 27600d163575Sopenharmony_ci struct udp_hdr *udphdr = NULL; 27610d163575Sopenharmony_ci struct ip6_dest_hdr *dest_hdr = NULL; 27620d163575Sopenharmony_ci struct ip6_frag_hdr *frag_hdr = NULL; 27630d163575Sopenharmony_ci u8_t nexth; 27640d163575Sopenharmony_ci u16_t hlen = 0; 27650d163575Sopenharmony_ci 27660d163575Sopenharmony_ci LWIP_ERROR("netstat_get_udp6_sendQLen: NULL pcb received\n", (udppcb != NULL), return -1); 27670d163575Sopenharmony_ci LWIP_ERROR("netstat_get_udp6_sendQLen: NULL pbuf received\n", (udpbuf != NULL), return -1); 27680d163575Sopenharmony_ci 27690d163575Sopenharmony_ci iphdr = (struct ip6_hdr *)udpbuf->payload; 27700d163575Sopenharmony_ci 27710d163575Sopenharmony_ci if (!(ip6_addr_cmp(&iphdr->dest, ip_2_ip6(&udppcb->remote_ip)) && 27720d163575Sopenharmony_ci (ip_addr_isany(&udppcb->local_ip) || 27730d163575Sopenharmony_ci ip6_addr_cmp(&iphdr->src, ip_2_ip6(&udppcb->local_ip))))) { 27740d163575Sopenharmony_ci goto FUNC_OUT; 27750d163575Sopenharmony_ci } 27760d163575Sopenharmony_ci 27770d163575Sopenharmony_ci len = IP6_HLEN; 27780d163575Sopenharmony_ci if (pbuf_header(udpbuf, (s16_t)(-(s16_t)(len)))) { 27790d163575Sopenharmony_ci goto FUNC_OUT; 27800d163575Sopenharmony_ci } 27810d163575Sopenharmony_ci 27820d163575Sopenharmony_ci offset = len; 27830d163575Sopenharmony_ci 27840d163575Sopenharmony_ci nexth = IP6H_NEXTH(iphdr); 27850d163575Sopenharmony_ci while (offset < udpbuf->tot_len) { 27860d163575Sopenharmony_ci if (nexth == IP6_NEXTH_NONE || nexth == IP6_NEXTH_UDP || nexth == IP6_NEXTH_UDPLITE) { 27870d163575Sopenharmony_ci break; 27880d163575Sopenharmony_ci } 27890d163575Sopenharmony_ci switch (nexth) { 27900d163575Sopenharmony_ci case IP6_NEXTH_HOPBYHOP: 27910d163575Sopenharmony_ci case IP6_NEXTH_ROUTING: 27920d163575Sopenharmony_ci nexth = *((u8_t *)udpbuf->payload); 27930d163575Sopenharmony_ci hlen = (u16_t)(8 * (1 + *((u8_t *)udpbuf->payload + 1))); 27940d163575Sopenharmony_ci break; 27950d163575Sopenharmony_ci case IP6_NEXTH_DESTOPTS: 27960d163575Sopenharmony_ci nexth = *((u8_t *)udpbuf->payload); 27970d163575Sopenharmony_ci dest_hdr = (struct ip6_dest_hdr *)udpbuf->payload; 27980d163575Sopenharmony_ci hlen = (u16_t)(8 * (1 + dest_hdr->_hlen)); 27990d163575Sopenharmony_ci break; 28000d163575Sopenharmony_ci case IP6_NEXTH_FRAGMENT: 28010d163575Sopenharmony_ci frag_hdr = (struct ip6_frag_hdr *)udpbuf->payload; 28020d163575Sopenharmony_ci nexth = frag_hdr->_nexth; 28030d163575Sopenharmony_ci hlen = IP6_FRAG_HLEN; 28040d163575Sopenharmony_ci break; 28050d163575Sopenharmony_ci default: 28060d163575Sopenharmony_ci /* Unknown next_header */ 28070d163575Sopenharmony_ci goto FUNC_OUT; 28080d163575Sopenharmony_ci } 28090d163575Sopenharmony_ci 28100d163575Sopenharmony_ci (void)pbuf_header(udpbuf, (s16_t)(-(s16_t)hlen)); 28110d163575Sopenharmony_ci offset = (u16_t)(offset + hlen); 28120d163575Sopenharmony_ci } 28130d163575Sopenharmony_ci 28140d163575Sopenharmony_ci /* If the while loop test condition failed , then revert the last offset change */ 28150d163575Sopenharmony_ci if (offset >= udpbuf->tot_len) { 28160d163575Sopenharmony_ci offset = (u16_t)(offset - hlen); 28170d163575Sopenharmony_ci goto FUNC_OUT; 28180d163575Sopenharmony_ci } 28190d163575Sopenharmony_ci 28200d163575Sopenharmony_ci LWIP_ERROR("Transport option should be UDP", (nexth == IP6_NEXTH_UDP || nexth == IP6_NEXTH_UDPLITE), goto FUNC_OUT); 28210d163575Sopenharmony_ci 28220d163575Sopenharmony_ci if (offset > iphdr->_plen) { 28230d163575Sopenharmony_ci goto FUNC_OUT; 28240d163575Sopenharmony_ci } 28250d163575Sopenharmony_ci 28260d163575Sopenharmony_ci /* check if there is enough space for at least udp header available */ 28270d163575Sopenharmony_ci if (udpbuf->tot_len < UDP_HLEN) { 28280d163575Sopenharmony_ci goto FUNC_OUT; 28290d163575Sopenharmony_ci } 28300d163575Sopenharmony_ci 28310d163575Sopenharmony_ci udphdr = (struct udp_hdr *)udpbuf->payload; 28320d163575Sopenharmony_ci if ((ntohs(udphdr->dest) == udppcb->remote_port) && (ntohs(udphdr->src) == udppcb->local_port)) { 28330d163575Sopenharmony_ci if (ntohs(udphdr->len) > UDP_HLEN) { 28340d163575Sopenharmony_ci sendLen = ntohs(udphdr->len) - UDP_HLEN; 28350d163575Sopenharmony_ci } else { 28360d163575Sopenharmony_ci sendLen = udpbuf->tot_len - UDP_HLEN; 28370d163575Sopenharmony_ci } 28380d163575Sopenharmony_ci } 28390d163575Sopenharmony_ci 28400d163575Sopenharmony_ciFUNC_OUT: 28410d163575Sopenharmony_ci (void)pbuf_header(udpbuf, (s16_t)offset); // can not cross max limit of s16_t 28420d163575Sopenharmony_ci return sendLen; 28430d163575Sopenharmony_ci} 28440d163575Sopenharmony_ci#endif 28450d163575Sopenharmony_ci 28460d163575Sopenharmony_ci#if LWIP_IPV4 28470d163575Sopenharmony_ciint netstat_get_udp_sendQLen(struct udp_pcb *udppcb, struct pbuf *udpbuf) 28480d163575Sopenharmony_ci{ 28490d163575Sopenharmony_ci int sendLen = -1; 28500d163575Sopenharmony_ci u16_t offset = 0, len; 28510d163575Sopenharmony_ci struct ip_hdr *iphdr = NULL; 28520d163575Sopenharmony_ci struct udp_hdr *udphdr = NULL; 28530d163575Sopenharmony_ci 28540d163575Sopenharmony_ci LWIP_ERROR("netstat_get_udp_sendQLen: NULL pcb received\n", (udppcb != NULL), return -1); 28550d163575Sopenharmony_ci LWIP_ERROR("netstat_get_udp_sendQLen: NULL pbuf received\n", (udpbuf != NULL), return -1); 28560d163575Sopenharmony_ci 28570d163575Sopenharmony_ci iphdr = (struct ip_hdr *)udpbuf->payload; 28580d163575Sopenharmony_ci 28590d163575Sopenharmony_ci if (!(ip4_addr_cmp(&iphdr->dest, ip_2_ip4(&udppcb->remote_ip)) && 28600d163575Sopenharmony_ci (ip_addr_isany(&udppcb->local_ip) || 28610d163575Sopenharmony_ci ip4_addr_cmp(&iphdr->src, ip_2_ip4(&udppcb->local_ip))))) { 28620d163575Sopenharmony_ci goto FUNC_OUT; 28630d163575Sopenharmony_ci } 28640d163575Sopenharmony_ci#if LWIP_UDPLITE 28650d163575Sopenharmony_ci if ((IPH_PROTO(iphdr) != IP_PROTO_UDP) && (IPH_PROTO(iphdr) != IP_PROTO_UDPLITE)) { 28660d163575Sopenharmony_ci#else 28670d163575Sopenharmony_ci if (IPH_PROTO(iphdr) != IP_PROTO_UDP) { 28680d163575Sopenharmony_ci#endif 28690d163575Sopenharmony_ci goto FUNC_OUT; 28700d163575Sopenharmony_ci } 28710d163575Sopenharmony_ci 28720d163575Sopenharmony_ci if ((ntohs(IPH_OFFSET(iphdr)) & IP_OFFMASK) != 0) { 28730d163575Sopenharmony_ci goto FUNC_OUT; 28740d163575Sopenharmony_ci } 28750d163575Sopenharmony_ci 28760d163575Sopenharmony_ci len = (u16_t)(IPH_HL(iphdr) * 4); 28770d163575Sopenharmony_ci if (pbuf_header(udpbuf, (s16_t)(-len))) { 28780d163575Sopenharmony_ci goto FUNC_OUT; 28790d163575Sopenharmony_ci } 28800d163575Sopenharmony_ci 28810d163575Sopenharmony_ci offset = (u16_t)(offset + len); 28820d163575Sopenharmony_ci 28830d163575Sopenharmony_ci udphdr = (struct udp_hdr *)udpbuf->payload; 28840d163575Sopenharmony_ci if ((ntohs(udphdr->dest) == udppcb->remote_port) && (ntohs(udphdr->src) == udppcb->local_port)) { 28850d163575Sopenharmony_ci sendLen = ntohs(udphdr->len) - UDP_HLEN; 28860d163575Sopenharmony_ci } 28870d163575Sopenharmony_ci 28880d163575Sopenharmony_ciFUNC_OUT: 28890d163575Sopenharmony_ci (void)pbuf_header(udpbuf, (s16_t)offset); 28900d163575Sopenharmony_ci return sendLen; 28910d163575Sopenharmony_ci} 28920d163575Sopenharmony_ci#endif 28930d163575Sopenharmony_ci 28940d163575Sopenharmony_ciint netstat_tcp_recvq(struct tcp_pcb *tpcb) 28950d163575Sopenharmony_ci{ 28960d163575Sopenharmony_ci unsigned int retVal = 0; 28970d163575Sopenharmony_ci#if LWIP_SO_RCVBUF 28980d163575Sopenharmony_ci struct netconn *conn = NULL; 28990d163575Sopenharmony_ci#endif 29000d163575Sopenharmony_ci 29010d163575Sopenharmony_ci LWIP_ERROR("netstat_tcp_recvq: Received NULL pcb\n", (tpcb != NULL), return 0); 29020d163575Sopenharmony_ci 29030d163575Sopenharmony_ci#if LWIP_SO_RCVBUF 29040d163575Sopenharmony_ci conn = (struct netconn *)tpcb->callback_arg; 29050d163575Sopenharmony_ci if (conn != NULL) { 29060d163575Sopenharmony_ci switch (conn->type) { 29070d163575Sopenharmony_ci case NETCONN_TCP: 29080d163575Sopenharmony_ci case NETCONN_RAW: 29090d163575Sopenharmony_ci#if LWIP_IPV6 29100d163575Sopenharmony_ci case NETCONN_RAW_IPV6: 29110d163575Sopenharmony_ci case NETCONN_UDP_IPV6: 29120d163575Sopenharmony_ci#endif 29130d163575Sopenharmony_ci case NETCONN_UDP: 29140d163575Sopenharmony_ci SYS_ARCH_GET(((unsigned int)conn->recv_avail), retVal); // + conn->lrcv_left 29150d163575Sopenharmony_ci break; 29160d163575Sopenharmony_ci default: 29170d163575Sopenharmony_ci retVal = 0; /* ur... very ugly, damn DHCP DNS and SNTP */ 29180d163575Sopenharmony_ci } 29190d163575Sopenharmony_ci } 29200d163575Sopenharmony_ci#endif 29210d163575Sopenharmony_ci 29220d163575Sopenharmony_ci return (int)retVal; 29230d163575Sopenharmony_ci} 29240d163575Sopenharmony_ci 29250d163575Sopenharmony_ciint netstat_tcp_sendq(struct tcp_pcb *tpcb) 29260d163575Sopenharmony_ci{ 29270d163575Sopenharmony_ci int retVal = 0; 29280d163575Sopenharmony_ci struct tcp_seg *useg = NULL; 29290d163575Sopenharmony_ci 29300d163575Sopenharmony_ci LWIP_ERROR("netstat_tcp_sendq: Received NULL pcb\n", (tpcb != NULL), return 0); 29310d163575Sopenharmony_ci 29320d163575Sopenharmony_ci for (useg = tpcb->unacked; useg != NULL; useg = useg->next) { 29330d163575Sopenharmony_ci retVal = retVal + useg->len; 29340d163575Sopenharmony_ci } 29350d163575Sopenharmony_ci 29360d163575Sopenharmony_ci return retVal; 29370d163575Sopenharmony_ci} 29380d163575Sopenharmony_ci 29390d163575Sopenharmony_ci#if LWIP_IPV6 29400d163575Sopenharmony_ciint netstat_udp_sendq6(struct udp_pcb *upcb) 29410d163575Sopenharmony_ci{ 29420d163575Sopenharmony_ci int retLen = 0; 29430d163575Sopenharmony_ci int ret; 29440d163575Sopenharmony_ci int idx = 0; 29450d163575Sopenharmony_ci int i; 29460d163575Sopenharmony_ci#if LWIP_ND6_QUEUEING 29470d163575Sopenharmony_ci struct nd6_q_entry *neibq = NULL; 29480d163575Sopenharmony_ci#endif 29490d163575Sopenharmony_ci 29500d163575Sopenharmony_ci LWIP_ERROR("netstat_udp_sendq6: Received NULL pcb\n", (upcb != NULL), return 0); 29510d163575Sopenharmony_ci 29520d163575Sopenharmony_ci for (i = 0; i < LWIP_ND6_NUM_NEIGHBORS; i++) { 29530d163575Sopenharmony_ci if (neighbor_cache[i].state != ND6_NO_ENTRY) { 29540d163575Sopenharmony_ci if (ip6_addr_cmp(&upcb->remote_ip.u_addr.ip6, &neighbor_cache[i].next_hop_address)) { 29550d163575Sopenharmony_ci idx = i; 29560d163575Sopenharmony_ci break; 29570d163575Sopenharmony_ci } 29580d163575Sopenharmony_ci } 29590d163575Sopenharmony_ci } 29600d163575Sopenharmony_ci#if LWIP_ND6_QUEUEING 29610d163575Sopenharmony_ci for (neibq = neighbor_cache[idx].q; neibq != NULL; neibq = neibq->next) { 29620d163575Sopenharmony_ci ret = netstat_get_udp_sendQLen6(upcb, neibq->p); 29630d163575Sopenharmony_ci if (ret >= 0) { 29640d163575Sopenharmony_ci retLen += ret; 29650d163575Sopenharmony_ci } 29660d163575Sopenharmony_ci } 29670d163575Sopenharmony_ci#else 29680d163575Sopenharmony_ci ret = netstat_get_udp_sendQLen6(upcb, neighbor_cache[idx].q); 29690d163575Sopenharmony_ci if (ret >= 0) { 29700d163575Sopenharmony_ci retLen += ret; 29710d163575Sopenharmony_ci } 29720d163575Sopenharmony_ci#endif 29730d163575Sopenharmony_ci return retLen; 29740d163575Sopenharmony_ci} 29750d163575Sopenharmony_ci#endif 29760d163575Sopenharmony_ci 29770d163575Sopenharmony_ci#if LWIP_IPV4 29780d163575Sopenharmony_ciint netstat_udp_sendq(struct udp_pcb *upcb) 29790d163575Sopenharmony_ci{ 29800d163575Sopenharmony_ci int retLen = 0; 29810d163575Sopenharmony_ci int ret; 29820d163575Sopenharmony_ci int arpidx = -1; 29830d163575Sopenharmony_ci int i; 29840d163575Sopenharmony_ci#if ARP_QUEUEING 29850d163575Sopenharmony_ci struct etharp_q_entry *arpq = NULL; 29860d163575Sopenharmony_ci#endif 29870d163575Sopenharmony_ci 29880d163575Sopenharmony_ci LWIP_ERROR("netstat_udp_sendq: Received NULL pcb\n", (upcb != NULL), return 0); 29890d163575Sopenharmony_ci 29900d163575Sopenharmony_ci for (i = 0; i < ARP_TABLE_SIZE; ++i) { 29910d163575Sopenharmony_ci if (arp_table[i].state != ETHARP_STATE_EMPTY) { 29920d163575Sopenharmony_ci if (ip4_addr_cmp(ip_2_ip4(&upcb->remote_ip), &arp_table[i].ipaddr)) { 29930d163575Sopenharmony_ci arpidx = i; 29940d163575Sopenharmony_ci break; 29950d163575Sopenharmony_ci } 29960d163575Sopenharmony_ci } 29970d163575Sopenharmony_ci } 29980d163575Sopenharmony_ci 29990d163575Sopenharmony_ci if (arpidx >= 0) { 30000d163575Sopenharmony_ci#if ARP_QUEUEING 30010d163575Sopenharmony_ci for (arpq = arp_table[arpidx].q; arpq != NULL; arpq = arpq->next) { 30020d163575Sopenharmony_ci ret = netstat_get_udp_sendQLen(upcb, arpq->p); 30030d163575Sopenharmony_ci if (ret > 0) { 30040d163575Sopenharmony_ci retLen += ret; 30050d163575Sopenharmony_ci if (retLen <= 0) { // overflow, set rteLen = -1 to indicate 30060d163575Sopenharmony_ci retLen = -1; 30070d163575Sopenharmony_ci break; 30080d163575Sopenharmony_ci } 30090d163575Sopenharmony_ci } 30100d163575Sopenharmony_ci } 30110d163575Sopenharmony_ci#else 30120d163575Sopenharmony_ci ret = netstat_get_udp_sendQLen(upcb, arp_table[arpidx].q); 30130d163575Sopenharmony_ci if (ret > 0) { 30140d163575Sopenharmony_ci retLen += ret; 30150d163575Sopenharmony_ci if (retLen <= 0) { // overflow, set rteLen = -1 to indicate 30160d163575Sopenharmony_ci retLen = -1; 30170d163575Sopenharmony_ci } 30180d163575Sopenharmony_ci } 30190d163575Sopenharmony_ci#endif 30200d163575Sopenharmony_ci } 30210d163575Sopenharmony_ci return retLen; 30220d163575Sopenharmony_ci} 30230d163575Sopenharmony_ci#endif 30240d163575Sopenharmony_ciint netstat_netconn_recvq(const struct netconn *conn) 30250d163575Sopenharmony_ci{ 30260d163575Sopenharmony_ci unsigned int retVal = 0; 30270d163575Sopenharmony_ci 30280d163575Sopenharmony_ci#if LWIP_SO_RCVBUF 30290d163575Sopenharmony_ci if (conn == NULL) { 30300d163575Sopenharmony_ci return 0; 30310d163575Sopenharmony_ci } 30320d163575Sopenharmony_ci 30330d163575Sopenharmony_ci switch (NETCONNTYPE_GROUP((unsigned int)(conn->type))) { 30340d163575Sopenharmony_ci case NETCONN_TCP: 30350d163575Sopenharmony_ci case NETCONN_RAW: 30360d163575Sopenharmony_ci#if PF_PKT_SUPPORT 30370d163575Sopenharmony_ci case NETCONN_PKT_RAW: 30380d163575Sopenharmony_ci#endif 30390d163575Sopenharmony_ci case NETCONN_UDP: 30400d163575Sopenharmony_ci SYS_ARCH_GET(((unsigned int)conn->recv_avail), retVal); // + conn->lrcv_left 30410d163575Sopenharmony_ci break; 30420d163575Sopenharmony_ci default: 30430d163575Sopenharmony_ci retVal = 0; /* ur... very ugly, damn DHCP DNS and SNTP */ 30440d163575Sopenharmony_ci } 30450d163575Sopenharmony_ci#endif 30460d163575Sopenharmony_ci return (int)retVal; 30470d163575Sopenharmony_ci} 30480d163575Sopenharmony_ci 30490d163575Sopenharmony_ciint netstat_netconn_sendq(struct netconn *conn) 30500d163575Sopenharmony_ci{ 30510d163575Sopenharmony_ci int retVal = 0; 30520d163575Sopenharmony_ci 30530d163575Sopenharmony_ci if (conn == NULL) { 30540d163575Sopenharmony_ci return 0; 30550d163575Sopenharmony_ci } 30560d163575Sopenharmony_ci 30570d163575Sopenharmony_ci switch (NETCONNTYPE_GROUP((unsigned int)(conn->type))) { 30580d163575Sopenharmony_ci case NETCONN_TCP: 30590d163575Sopenharmony_ci retVal = netstat_tcp_sendq(conn->pcb.tcp); 30600d163575Sopenharmony_ci break; 30610d163575Sopenharmony_ci case NETCONN_RAW: 30620d163575Sopenharmony_ci retVal = 0; 30630d163575Sopenharmony_ci break; 30640d163575Sopenharmony_ci#if PF_PKT_SUPPORT 30650d163575Sopenharmony_ci case NETCONN_PKT_RAW: 30660d163575Sopenharmony_ci retVal = 0; /* always be 0 as frame send to driver directly */ 30670d163575Sopenharmony_ci break; 30680d163575Sopenharmony_ci#endif 30690d163575Sopenharmony_ci case NETCONN_UDP: 30700d163575Sopenharmony_ci retVal = netstat_udp_sendq(conn->pcb.udp); 30710d163575Sopenharmony_ci break; 30720d163575Sopenharmony_ci default: 30730d163575Sopenharmony_ci retVal = 0; /* ur... very ugly, damn DHCP DNS and SNTP */ 30740d163575Sopenharmony_ci } 30750d163575Sopenharmony_ci 30760d163575Sopenharmony_ci return retVal; 30770d163575Sopenharmony_ci} 30780d163575Sopenharmony_civoid netstat_internal(void *ctx) 30790d163575Sopenharmony_ci{ 30800d163575Sopenharmony_ci s8_t local_ip_port[64] = {0}; 30810d163575Sopenharmony_ci s8_t remote_ip_port[64] = {0}; 30820d163575Sopenharmony_ci struct tcp_pcb *tpcb = NULL; 30830d163575Sopenharmony_ci struct tcp_pcb_listen *lpcb = NULL; 30840d163575Sopenharmony_ci struct udp_pcb *upcb = NULL; 30850d163575Sopenharmony_ci struct raw_pcb *rpcb = NULL; 30860d163575Sopenharmony_ci s8_t *entry_buf = NULL; 30870d163575Sopenharmony_ci u32_t entry_buf_len; 30880d163575Sopenharmony_ci u32_t entry_buf_offset; 30890d163575Sopenharmony_ci struct netstat_data *ndata = (struct netstat_data *)ctx; 30900d163575Sopenharmony_ci int iRet; 30910d163575Sopenharmony_ci int recvQlen = 0; 30920d163575Sopenharmony_ci int sendQlen = 0; 30930d163575Sopenharmony_ci u_int proto; 30940d163575Sopenharmony_ci#if PF_PKT_SUPPORT 30950d163575Sopenharmony_ci u8_t netif_name[IFNAMSIZ]; 30960d163575Sopenharmony_ci struct netif *netif = NULL; 30970d163575Sopenharmony_ci#endif 30980d163575Sopenharmony_ci 30990d163575Sopenharmony_ci if (ndata == NULL) { 31000d163575Sopenharmony_ci return; 31010d163575Sopenharmony_ci } 31020d163575Sopenharmony_ci entry_buf = ndata->netstat_out_buf; 31030d163575Sopenharmony_ci entry_buf_len = ndata->netstat_out_buf_len; 31040d163575Sopenharmony_ci entry_buf_offset = 0; 31050d163575Sopenharmony_ci 31060d163575Sopenharmony_ci if (entry_buf == NULL) { 31070d163575Sopenharmony_ci goto out; 31080d163575Sopenharmony_ci } 31090d163575Sopenharmony_ci iRet = snprintf_s((char *)(entry_buf + entry_buf_offset), entry_buf_len, entry_buf_len - 1, 31100d163575Sopenharmony_ci "========== total sockets %d ====== unused sockets %d ==========\n", 31110d163575Sopenharmony_ci LWIP_CONFIG_NUM_SOCKETS, get_unused_socket_num()); 31120d163575Sopenharmony_ci if ((iRet <= 0) || ((u32_t)(iRet) >= entry_buf_len)) { 31130d163575Sopenharmony_ci goto out; 31140d163575Sopenharmony_ci } 31150d163575Sopenharmony_ci entry_buf_len -= (u32_t)(iRet); 31160d163575Sopenharmony_ci entry_buf_offset += (u32_t)(iRet); 31170d163575Sopenharmony_ci 31180d163575Sopenharmony_ci#if LWIP_TCP 31190d163575Sopenharmony_ci if (tcp_active_pcbs != NULL || tcp_bound_pcbs != NULL || tcp_tw_pcbs != NULL || tcp_listen_pcbs.pcbs != NULL) { 31200d163575Sopenharmony_ci iRet = snprintf_s((char *)(entry_buf + entry_buf_offset), entry_buf_len, entry_buf_len - 1, 31210d163575Sopenharmony_ci "%-8s%-12s%-12s%-24s%-24s%-16s\n", 31220d163575Sopenharmony_ci "Proto", "Recv-Q", "Send-Q", "Local Address", "Foreign Address", "State"); 31230d163575Sopenharmony_ci if ((iRet <= 0) || ((u32_t)(iRet) >= entry_buf_len)) { 31240d163575Sopenharmony_ci goto out; 31250d163575Sopenharmony_ci } 31260d163575Sopenharmony_ci entry_buf_len -= (u32_t)(iRet); 31270d163575Sopenharmony_ci entry_buf_offset += (u32_t)(iRet); 31280d163575Sopenharmony_ci 31290d163575Sopenharmony_ci for (tpcb = tcp_active_pcbs; tpcb != NULL; tpcb = tpcb->next) { 31300d163575Sopenharmony_ci iRet = snprintf_s((char *)local_ip_port, sizeof(local_ip_port), (sizeof(local_ip_port) - 1), 31310d163575Sopenharmony_ci "%s:%d", ipaddr_ntoa(&tpcb->local_ip), tpcb->local_port); 31320d163575Sopenharmony_ci if ((iRet <= 0) || ((u32_t)(iRet) >= sizeof(local_ip_port))) { 31330d163575Sopenharmony_ci goto out; 31340d163575Sopenharmony_ci } 31350d163575Sopenharmony_ci 31360d163575Sopenharmony_ci iRet = snprintf_s((char *)remote_ip_port, sizeof(remote_ip_port), (sizeof(remote_ip_port) - 1), 31370d163575Sopenharmony_ci "%s:%d", ipaddr_ntoa(&tpcb->remote_ip), tpcb->remote_port); 31380d163575Sopenharmony_ci if ((iRet <= 0) || ((u32_t)(iRet) >= sizeof(remote_ip_port))) { 31390d163575Sopenharmony_ci goto out; 31400d163575Sopenharmony_ci } 31410d163575Sopenharmony_ci if (tpcb->state == SYN_RCVD) { 31420d163575Sopenharmony_ci recvQlen = 0; 31430d163575Sopenharmony_ci sendQlen = 0; 31440d163575Sopenharmony_ci } else { 31450d163575Sopenharmony_ci recvQlen = netstat_netconn_recvq(tpcb->callback_arg); 31460d163575Sopenharmony_ci sendQlen = netstat_netconn_sendq(tpcb->callback_arg); 31470d163575Sopenharmony_ci } 31480d163575Sopenharmony_ci iRet = snprintf_s((char *)(entry_buf + entry_buf_offset), entry_buf_len, entry_buf_len - 1, 31490d163575Sopenharmony_ci IP_IS_V6(&tpcb->local_ip) ? "%-8s%-12d%-12d%-39s%-39s%-16s\n" : 31500d163575Sopenharmony_ci "%-8s%-12d%-12d%-24s%-24s%-16s\n", 31510d163575Sopenharmony_ci IP_IS_V6(&tpcb->local_ip) ? "tcp-ip6" : "tcp", 31520d163575Sopenharmony_ci recvQlen, sendQlen, local_ip_port, remote_ip_port, tcp_state_str[tpcb->state]); 31530d163575Sopenharmony_ci if ((iRet <= 0) || ((u32_t)(iRet) >= entry_buf_len)) { 31540d163575Sopenharmony_ci goto out; 31550d163575Sopenharmony_ci } 31560d163575Sopenharmony_ci entry_buf_len -= (u32_t)(iRet); 31570d163575Sopenharmony_ci entry_buf_offset += (u32_t)(iRet); 31580d163575Sopenharmony_ci } 31590d163575Sopenharmony_ci 31600d163575Sopenharmony_ci /* For bound PCBs */ 31610d163575Sopenharmony_ci sendQlen = 0; 31620d163575Sopenharmony_ci recvQlen = 0; 31630d163575Sopenharmony_ci 31640d163575Sopenharmony_ci for (tpcb = tcp_bound_pcbs; tpcb != NULL; tpcb = tpcb->next) { 31650d163575Sopenharmony_ci iRet = snprintf_s((char *)local_ip_port, sizeof(local_ip_port), (sizeof(local_ip_port) - 1), 31660d163575Sopenharmony_ci "%s:%d", ipaddr_ntoa(&tpcb->local_ip), tpcb->local_port); 31670d163575Sopenharmony_ci if ((iRet <= 0) || ((u32_t)(iRet) >= sizeof(local_ip_port))) { 31680d163575Sopenharmony_ci goto out; 31690d163575Sopenharmony_ci } 31700d163575Sopenharmony_ci 31710d163575Sopenharmony_ci iRet = snprintf_s((char *)remote_ip_port, sizeof(remote_ip_port), (sizeof(remote_ip_port) - 1), 31720d163575Sopenharmony_ci "%s:%d", ipaddr_ntoa(&tpcb->remote_ip), tpcb->remote_port); 31730d163575Sopenharmony_ci if ((iRet <= 0) || ((u32_t)(iRet) >= sizeof(remote_ip_port))) { 31740d163575Sopenharmony_ci goto out; 31750d163575Sopenharmony_ci } 31760d163575Sopenharmony_ci 31770d163575Sopenharmony_ci iRet = snprintf_s((char *)(entry_buf + entry_buf_offset), entry_buf_len, entry_buf_len - 1, 31780d163575Sopenharmony_ci IP_IS_V6(&tpcb->local_ip) ? "%-8s%-12d%-12d%-39s%-39s%-16s\n" : 31790d163575Sopenharmony_ci "%-8s%-12d%-12d%-24s%-24s%-16s\n", 31800d163575Sopenharmony_ci IP_IS_V6(&tpcb->local_ip) ? "tcp-ip6" : "tcp", 31810d163575Sopenharmony_ci recvQlen, sendQlen, local_ip_port, remote_ip_port, tcp_state_str[tpcb->state]); 31820d163575Sopenharmony_ci if ((iRet <= 0) || ((u32_t)(iRet) >= entry_buf_len)) { 31830d163575Sopenharmony_ci goto out; 31840d163575Sopenharmony_ci } 31850d163575Sopenharmony_ci entry_buf_len -= (u32_t)(iRet); 31860d163575Sopenharmony_ci entry_buf_offset += (u32_t)(iRet); 31870d163575Sopenharmony_ci } 31880d163575Sopenharmony_ci 31890d163575Sopenharmony_ci for (tpcb = tcp_tw_pcbs; tpcb != NULL; tpcb = tpcb->next) { 31900d163575Sopenharmony_ci iRet = snprintf_s((char *)local_ip_port, sizeof(local_ip_port), (sizeof(local_ip_port) - 1), 31910d163575Sopenharmony_ci "%s:%d", ipaddr_ntoa(&tpcb->local_ip), tpcb->local_port); 31920d163575Sopenharmony_ci if ((iRet <= 0) || ((u32_t)(iRet) >= sizeof(local_ip_port))) { 31930d163575Sopenharmony_ci goto out; 31940d163575Sopenharmony_ci } 31950d163575Sopenharmony_ci 31960d163575Sopenharmony_ci iRet = snprintf_s((char *)remote_ip_port, sizeof(remote_ip_port), (sizeof(remote_ip_port) - 1), 31970d163575Sopenharmony_ci "%s:%d", ipaddr_ntoa(&tpcb->remote_ip), tpcb->remote_port); 31980d163575Sopenharmony_ci if ((iRet <= 0) || ((u32_t)(iRet) >= sizeof(remote_ip_port))) { 31990d163575Sopenharmony_ci goto out; 32000d163575Sopenharmony_ci } 32010d163575Sopenharmony_ci 32020d163575Sopenharmony_ci recvQlen = netstat_netconn_recvq(tpcb->callback_arg); 32030d163575Sopenharmony_ci sendQlen = netstat_netconn_sendq(tpcb->callback_arg); 32040d163575Sopenharmony_ci iRet = snprintf_s((char *)(entry_buf + entry_buf_offset), entry_buf_len, entry_buf_len - 1, 32050d163575Sopenharmony_ci IP_IS_V6(&tpcb->local_ip) ? "%-8s%-12d%-12d%-39s%-39s%-16s\n" : 32060d163575Sopenharmony_ci "%-8s%-12d%-12d%-24s%-24s%-16s\n", 32070d163575Sopenharmony_ci IP_IS_V6(&tpcb->local_ip) ? "tcp-ip6" : "tcp", 32080d163575Sopenharmony_ci recvQlen, sendQlen, local_ip_port, remote_ip_port, tcp_state_str[tpcb->state]); 32090d163575Sopenharmony_ci if ((iRet <= 0) || ((u32_t)(iRet) >= entry_buf_len)) { 32100d163575Sopenharmony_ci goto out; 32110d163575Sopenharmony_ci } 32120d163575Sopenharmony_ci entry_buf_len -= (u32_t)(iRet); 32130d163575Sopenharmony_ci entry_buf_offset += (u32_t)(iRet); 32140d163575Sopenharmony_ci } 32150d163575Sopenharmony_ci 32160d163575Sopenharmony_ci /* For listen PCBs */ 32170d163575Sopenharmony_ci sendQlen = 0; 32180d163575Sopenharmony_ci 32190d163575Sopenharmony_ci for (lpcb = tcp_listen_pcbs.listen_pcbs; lpcb != NULL; lpcb = lpcb->next) { 32200d163575Sopenharmony_ci iRet = snprintf_s((char *)local_ip_port, sizeof(local_ip_port), (sizeof(local_ip_port) - 1), 32210d163575Sopenharmony_ci "%s:%d", ipaddr_ntoa(&lpcb->local_ip), lpcb->local_port); 32220d163575Sopenharmony_ci if ((iRet <= 0) || ((u32_t)(iRet) >= sizeof(local_ip_port))) { 32230d163575Sopenharmony_ci goto out; 32240d163575Sopenharmony_ci } 32250d163575Sopenharmony_ci 32260d163575Sopenharmony_ci iRet = snprintf_s((char *)remote_ip_port, sizeof(remote_ip_port), (sizeof(remote_ip_port) - 1), 32270d163575Sopenharmony_ci "%s:%d", ipaddr_ntoa(&lpcb->remote_ip), 0); 32280d163575Sopenharmony_ci if ((iRet <= 0) || ((u32_t)(iRet) >= sizeof(remote_ip_port))) { 32290d163575Sopenharmony_ci goto out; 32300d163575Sopenharmony_ci } 32310d163575Sopenharmony_ci 32320d163575Sopenharmony_ci recvQlen = netstat_netconn_recvq(lpcb->callback_arg); 32330d163575Sopenharmony_ci 32340d163575Sopenharmony_ci iRet = snprintf_s((char *)(entry_buf + entry_buf_offset), entry_buf_len, entry_buf_len - 1, 32350d163575Sopenharmony_ci IP_IS_V6(&lpcb->local_ip) ? "%-8s%-12d%-12d%-39s%-39s%-16s\n" : 32360d163575Sopenharmony_ci "%-8s%-12d%-12d%-24s%-24s%-16s\n", 32370d163575Sopenharmony_ci IP_IS_V6(&lpcb->local_ip) ? "tcp-ip6" : "tcp", 32380d163575Sopenharmony_ci recvQlen, sendQlen, local_ip_port, remote_ip_port, tcp_state_str[lpcb->state]); 32390d163575Sopenharmony_ci if ((iRet <= 0) || ((u32_t)(iRet) >= entry_buf_len)) { 32400d163575Sopenharmony_ci goto out; 32410d163575Sopenharmony_ci } 32420d163575Sopenharmony_ci entry_buf_len -= (u32_t)(iRet); 32430d163575Sopenharmony_ci entry_buf_offset += (u32_t)(iRet); 32440d163575Sopenharmony_ci } 32450d163575Sopenharmony_ci } 32460d163575Sopenharmony_ci#endif 32470d163575Sopenharmony_ci#if LWIP_UDP 32480d163575Sopenharmony_ci if (udp_pcbs != NULL) { 32490d163575Sopenharmony_ci iRet = snprintf_s((char *)(entry_buf + entry_buf_offset), entry_buf_len, entry_buf_len - 1, 32500d163575Sopenharmony_ci "\n%-8s%-12s%-12s%-24s%-24s\n", 32510d163575Sopenharmony_ci "Proto", "Recv-Q", "Send-Q", "Local Address", "Foreign Address"); 32520d163575Sopenharmony_ci if ((iRet <= 0) || ((u32_t)(iRet) >= entry_buf_len)) { 32530d163575Sopenharmony_ci goto out; 32540d163575Sopenharmony_ci } 32550d163575Sopenharmony_ci entry_buf_len -= (u32_t)(iRet); 32560d163575Sopenharmony_ci entry_buf_offset += (u32_t)(iRet); 32570d163575Sopenharmony_ci 32580d163575Sopenharmony_ci for (upcb = udp_pcbs; upcb != NULL; upcb = upcb->next) { 32590d163575Sopenharmony_ci iRet = snprintf_s((char *)local_ip_port, sizeof(local_ip_port), (sizeof(local_ip_port) - 1), 32600d163575Sopenharmony_ci "%s:%d", ipaddr_ntoa(&upcb->local_ip), upcb->local_port); 32610d163575Sopenharmony_ci if ((iRet <= 0) || ((u32_t)(iRet) >= sizeof(local_ip_port))) { 32620d163575Sopenharmony_ci goto out; 32630d163575Sopenharmony_ci } 32640d163575Sopenharmony_ci 32650d163575Sopenharmony_ci iRet = snprintf_s((char *)remote_ip_port, sizeof(remote_ip_port), (sizeof(remote_ip_port) - 1), 32660d163575Sopenharmony_ci "%s:%d", ipaddr_ntoa(&upcb->remote_ip), upcb->remote_port); 32670d163575Sopenharmony_ci if ((iRet <= 0) || ((u32_t)(iRet) >= sizeof(remote_ip_port))) { 32680d163575Sopenharmony_ci goto out; 32690d163575Sopenharmony_ci } 32700d163575Sopenharmony_ci 32710d163575Sopenharmony_ci recvQlen = netstat_netconn_recvq(upcb->recv_arg); 32720d163575Sopenharmony_ci#if LWIP_IPV6 32730d163575Sopenharmony_ci sendQlen = IP_IS_V6(&upcb->local_ip) ? netstat_udp_sendq6(upcb) : netstat_netconn_sendq(upcb->recv_arg); 32740d163575Sopenharmony_ci#else 32750d163575Sopenharmony_ci sendQlen = netstat_netconn_sendq(upcb->recv_arg); 32760d163575Sopenharmony_ci#endif 32770d163575Sopenharmony_ci iRet = snprintf_s((char *)(entry_buf + entry_buf_offset), entry_buf_len, entry_buf_len - 1, 32780d163575Sopenharmony_ci IP_IS_V6(&upcb->local_ip) ? "%-8s%-12d%-12d%-39s%-39s%-16s\n" : 32790d163575Sopenharmony_ci "%-8s%-12d%-12d%-24s%-24s%-16s\n", 32800d163575Sopenharmony_ci IP_IS_V6(&upcb->local_ip) ? "udp-ip6" : "udp", 32810d163575Sopenharmony_ci recvQlen, sendQlen, local_ip_port, remote_ip_port, " "); 32820d163575Sopenharmony_ci if ((iRet <= 0) || ((u32_t)(iRet) >= entry_buf_len)) { 32830d163575Sopenharmony_ci goto out; 32840d163575Sopenharmony_ci } 32850d163575Sopenharmony_ci entry_buf_len -= (u32_t)(iRet); 32860d163575Sopenharmony_ci entry_buf_offset += (u32_t)(iRet); 32870d163575Sopenharmony_ci } 32880d163575Sopenharmony_ci } 32890d163575Sopenharmony_ci#endif 32900d163575Sopenharmony_ci 32910d163575Sopenharmony_ci#if LWIP_RAW 32920d163575Sopenharmony_ci if (raw_pcbs != NULL) { 32930d163575Sopenharmony_ci iRet = snprintf_s((char *)(entry_buf + entry_buf_offset), entry_buf_len, entry_buf_len - 1, 32940d163575Sopenharmony_ci "\n%-8s%-12s%-12s%-20s%-20s%-16s%-16s\n", 32950d163575Sopenharmony_ci "Type", "Recv-Q", "Send-Q", "Local Address", "Foreign Address", "Protocol", "HDRINCL"); 32960d163575Sopenharmony_ci if ((iRet <= 0) || ((u32_t)(iRet) >= entry_buf_len)) { 32970d163575Sopenharmony_ci goto out; 32980d163575Sopenharmony_ci } 32990d163575Sopenharmony_ci entry_buf_len -= (u32_t)(iRet); 33000d163575Sopenharmony_ci entry_buf_offset += (u32_t)(iRet); 33010d163575Sopenharmony_ci 33020d163575Sopenharmony_ci for (rpcb = raw_pcbs; rpcb != NULL; rpcb = rpcb->next) { 33030d163575Sopenharmony_ci iRet = snprintf_s((char *)local_ip_port, sizeof(local_ip_port), (sizeof(local_ip_port) - 1), 33040d163575Sopenharmony_ci "%s", ipaddr_ntoa(&rpcb->local_ip)); 33050d163575Sopenharmony_ci if ((iRet <= 0) || ((u32_t)(iRet) >= sizeof(local_ip_port))) { 33060d163575Sopenharmony_ci goto out; 33070d163575Sopenharmony_ci } 33080d163575Sopenharmony_ci 33090d163575Sopenharmony_ci iRet = snprintf_s((char *)remote_ip_port, sizeof(remote_ip_port), (sizeof(remote_ip_port) - 1), 33100d163575Sopenharmony_ci "%s", ipaddr_ntoa(&rpcb->remote_ip)); 33110d163575Sopenharmony_ci if ((iRet <= 0) || ((u32_t)(iRet) >= sizeof(remote_ip_port))) { 33120d163575Sopenharmony_ci goto out; 33130d163575Sopenharmony_ci } 33140d163575Sopenharmony_ci 33150d163575Sopenharmony_ci recvQlen = netstat_netconn_recvq(rpcb->recv_arg); 33160d163575Sopenharmony_ci sendQlen = netstat_netconn_sendq(rpcb->recv_arg); 33170d163575Sopenharmony_ci 33180d163575Sopenharmony_ci proto = rpcb->protocol; // raw_proto; 33190d163575Sopenharmony_ci iRet = snprintf_s((char *)(entry_buf + entry_buf_offset), entry_buf_len, entry_buf_len - 1, 33200d163575Sopenharmony_ci "%-8s%-12d%-12d%-20s%-20s%-16u%-16d\n", 33210d163575Sopenharmony_ci "raw", recvQlen, sendQlen, local_ip_port, remote_ip_port, proto, 0); // rpcb->hdrincl 33220d163575Sopenharmony_ci if ((iRet <= 0) || ((u32_t)(iRet) >= entry_buf_len)) { 33230d163575Sopenharmony_ci goto out; 33240d163575Sopenharmony_ci } 33250d163575Sopenharmony_ci entry_buf_len -= (u32_t)(iRet); 33260d163575Sopenharmony_ci entry_buf_offset += (u32_t)(iRet); 33270d163575Sopenharmony_ci } 33280d163575Sopenharmony_ci } 33290d163575Sopenharmony_ci#if PF_PKT_SUPPORT 33300d163575Sopenharmony_ci if (pkt_raw_pcbs != NULL) { 33310d163575Sopenharmony_ci iRet = snprintf_s((char *)(entry_buf + entry_buf_offset), entry_buf_len, entry_buf_len - 1, 33320d163575Sopenharmony_ci "\n%-12s%-12s%-12s%-16s%-12s\n", "Type", "Recv-Q", "Send-Q", "Protocol", "netif"); 33330d163575Sopenharmony_ci if ((iRet <= 0) || ((u32_t)(iRet) >= entry_buf_len)) { 33340d163575Sopenharmony_ci goto out; 33350d163575Sopenharmony_ci } 33360d163575Sopenharmony_ci entry_buf_len -= (u32_t)(iRet); 33370d163575Sopenharmony_ci entry_buf_offset += (u32_t)(iRet); 33380d163575Sopenharmony_ci 33390d163575Sopenharmony_ci for (rpcb = pkt_raw_pcbs; rpcb != NULL; rpcb = rpcb->next) { 33400d163575Sopenharmony_ci recvQlen = netstat_netconn_recvq(rpcb->recv_arg); 33410d163575Sopenharmony_ci sendQlen = netstat_netconn_sendq(rpcb->recv_arg); 33420d163575Sopenharmony_ci 33430d163575Sopenharmony_ci for (netif = netif_list; netif != NULL; netif = netif->next) { 33440d163575Sopenharmony_ci /* netif->ifindex and index */ 33450d163575Sopenharmony_ci if (netif_get_index(netif) == rpcb->netif_idx) { 33460d163575Sopenharmony_ci (void)snprintf_s((char *)netif_name, IFNAMSIZ, IFNAMSIZ - 1, "%s", netif_get_name(netif)); 33470d163575Sopenharmony_ci break; 33480d163575Sopenharmony_ci } 33490d163575Sopenharmony_ci } 33500d163575Sopenharmony_ci 33510d163575Sopenharmony_ci if (netif == NULL) { 33520d163575Sopenharmony_ci (void)snprintf_s((char *)netif_name, IFNAMSIZ, IFNAMSIZ - 1, "%s", "None"); 33530d163575Sopenharmony_ci } 33540d163575Sopenharmony_ci 33550d163575Sopenharmony_ci proto = rpcb->protocol; // ntohs(rpcb->proto.eth_proto); 33560d163575Sopenharmony_ci 33570d163575Sopenharmony_ci iRet = snprintf_s((char *)(entry_buf + entry_buf_offset), entry_buf_len, entry_buf_len - 1, 33580d163575Sopenharmony_ci "%-12s%-12d%-12d%-16x%-12s\n", "pkt-raw", recvQlen, sendQlen, proto, netif_name); 33590d163575Sopenharmony_ci if ((iRet <= 0) || ((u32_t)(iRet) >= entry_buf_len)) { 33600d163575Sopenharmony_ci goto out; 33610d163575Sopenharmony_ci } 33620d163575Sopenharmony_ci entry_buf_len -= (u32_t)(iRet); 33630d163575Sopenharmony_ci entry_buf_offset += (u32_t)(iRet); 33640d163575Sopenharmony_ci } 33650d163575Sopenharmony_ci } 33660d163575Sopenharmony_ci#endif 33670d163575Sopenharmony_ci#endif 33680d163575Sopenharmony_ci 33690d163575Sopenharmony_ciout: 33700d163575Sopenharmony_ci ndata->netstat_out_buf_updated_len = entry_buf_offset; 33710d163575Sopenharmony_ci sys_sem_signal(&ndata->cb_completed); 33720d163575Sopenharmony_ci return; 33730d163575Sopenharmony_ci} 33740d163575Sopenharmony_ci 33750d163575Sopenharmony_ciu32_t osShellNetstat(int argc, const char **argv) 33760d163575Sopenharmony_ci{ 33770d163575Sopenharmony_ci struct netstat_data ndata; 33780d163575Sopenharmony_ci err_t err; 33790d163575Sopenharmony_ci 33800d163575Sopenharmony_ci if (argc > 0) { 33810d163575Sopenharmony_ci PRINTK("\nUsage: netstat\n"); 33820d163575Sopenharmony_ci return LOS_NOK; 33830d163575Sopenharmony_ci } 33840d163575Sopenharmony_ci 33850d163575Sopenharmony_ci if (tcpip_init_finish == 0) { 33860d163575Sopenharmony_ci PRINTK("%s: tcpip_init have not been called\n", __FUNCTION__); 33870d163575Sopenharmony_ci return LOS_NOK; 33880d163575Sopenharmony_ci } 33890d163575Sopenharmony_ci 33900d163575Sopenharmony_ci ndata.netstat_out_buf = mem_malloc(MAX_NETSTAT_ENTRY); 33910d163575Sopenharmony_ci if (ndata.netstat_out_buf == NULL) { 33920d163575Sopenharmony_ci PRINTK("%s: no free mem\n", __FUNCTION__); 33930d163575Sopenharmony_ci return LOS_NOK; 33940d163575Sopenharmony_ci } 33950d163575Sopenharmony_ci ndata.netstat_out_buf_len = MAX_NETSTAT_ENTRY; 33960d163575Sopenharmony_ci ndata.netstat_out_buf_updated_len = 0; 33970d163575Sopenharmony_ci 33980d163575Sopenharmony_ci if (sys_sem_new(&ndata.cb_completed, 0) != ERR_OK) { 33990d163575Sopenharmony_ci goto err_hand; 34000d163575Sopenharmony_ci } 34010d163575Sopenharmony_ci 34020d163575Sopenharmony_ci err = tcpip_callback(netstat_internal, &ndata); 34030d163575Sopenharmony_ci if (err != ERR_OK) { 34040d163575Sopenharmony_ci sys_sem_free(&ndata.cb_completed); 34050d163575Sopenharmony_ci goto err_hand; 34060d163575Sopenharmony_ci } 34070d163575Sopenharmony_ci 34080d163575Sopenharmony_ci (void)sys_arch_sem_wait(&ndata.cb_completed, 0); 34090d163575Sopenharmony_ci sys_sem_free(&ndata.cb_completed); 34100d163575Sopenharmony_ci if ((ndata.netstat_out_buf_updated_len > 0) && (ndata.netstat_out_buf_updated_len < MAX_NETSTAT_ENTRY)) { 34110d163575Sopenharmony_ci PRINTK("%s\n", (char *)(ndata.netstat_out_buf)); 34120d163575Sopenharmony_ci mem_free(ndata.netstat_out_buf); 34130d163575Sopenharmony_ci return LOS_OK; 34140d163575Sopenharmony_ci } 34150d163575Sopenharmony_ci 34160d163575Sopenharmony_cierr_hand: 34170d163575Sopenharmony_ci mem_free(ndata.netstat_out_buf); 34180d163575Sopenharmony_ci ndata.netstat_out_buf = NULL; 34190d163575Sopenharmony_ci (void)(argv); 34200d163575Sopenharmony_ci return LOS_NOK; 34210d163575Sopenharmony_ci} 34220d163575Sopenharmony_ci#ifdef LOSCFG_SHELL 34230d163575Sopenharmony_ciSHELLCMD_ENTRY(netstat_shellcmd, CMD_TYPE_EX, "netstat", XARGS, (CmdCallBackFunc)osShellNetstat); 34240d163575Sopenharmony_ci#endif /* LOSCFG_SHELL */ 34250d163575Sopenharmony_ci 34260d163575Sopenharmony_ci#define NETIF_NAME_LEN 10 34270d163575Sopenharmony_ciSTATIC VOID OsShellDhclientUsage(VOID) 34280d163575Sopenharmony_ci{ 34290d163575Sopenharmony_ci PRINTK("<netif name>, start dhcp for netif name\n" 34300d163575Sopenharmony_ci "-x <netif name>, stop dhcp for netif name\n" 34310d163575Sopenharmony_ci "-h | --help, print dhclient command usage\n"); 34320d163575Sopenharmony_ci} 34330d163575Sopenharmony_ci 34340d163575Sopenharmony_ciu32_t OsShellDhclient(int argc, const char **argv) 34350d163575Sopenharmony_ci{ 34360d163575Sopenharmony_ci struct netif *netif = NULL; 34370d163575Sopenharmony_ci 34380d163575Sopenharmony_ci if (argc == 0) { 34390d163575Sopenharmony_ci OsShellDhclientUsage(); 34400d163575Sopenharmony_ci } else if (argc == 1) { 34410d163575Sopenharmony_ci if (strcmp(argv[0], "-h") == 0 || strcmp(argv[0], "--help") == 0) { 34420d163575Sopenharmony_ci OsShellDhclientUsage(); 34430d163575Sopenharmony_ci } else { 34440d163575Sopenharmony_ci netif = netif_find(argv[0]); 34450d163575Sopenharmony_ci if (netif != NULL) { 34460d163575Sopenharmony_ci (VOID)netifapi_dhcp_start(netif); 34470d163575Sopenharmony_ci } else { 34480d163575Sopenharmony_ci PRINTK("dhclient: invalid option: %s\n", argv[0]); 34490d163575Sopenharmony_ci OsShellDhclientUsage(); 34500d163575Sopenharmony_ci } 34510d163575Sopenharmony_ci } 34520d163575Sopenharmony_ci } else if (argc == 2) { 34530d163575Sopenharmony_ci if (strcmp(argv[0], "-x") == 0) { 34540d163575Sopenharmony_ci netif = netif_find(argv[1]); 34550d163575Sopenharmony_ci if (netif != NULL) { 34560d163575Sopenharmony_ci (VOID)netifapi_dhcp_stop(netif); 34570d163575Sopenharmony_ci } else { 34580d163575Sopenharmony_ci PRINTK("dhclient: invalid option: %s\n", argv[1]); 34590d163575Sopenharmony_ci OsShellDhclientUsage(); 34600d163575Sopenharmony_ci } 34610d163575Sopenharmony_ci } else { 34620d163575Sopenharmony_ci PRINTK("dhclient: invalid option: %s\n", argv[0]); 34630d163575Sopenharmony_ci OsShellDhclientUsage(); 34640d163575Sopenharmony_ci } 34650d163575Sopenharmony_ci } else { 34660d163575Sopenharmony_ci OsShellDhclientUsage(); 34670d163575Sopenharmony_ci } 34680d163575Sopenharmony_ci 34690d163575Sopenharmony_ci return 0; 34700d163575Sopenharmony_ci} 34710d163575Sopenharmony_ci 34720d163575Sopenharmony_ci#ifdef LOSCFG_SHELL 34730d163575Sopenharmony_ciSHELLCMD_ENTRY(dhclient_shellcmd, CMD_TYPE_EX, "dhclient", XARGS, (CmdCallBackFunc)OsShellDhclient); 34740d163575Sopenharmony_ci#endif /* LOSCFG_SHELL */ 34750d163575Sopenharmony_ci 34760d163575Sopenharmony_ci#ifdef LWIP_DEBUG_TCPSERVER 34770d163575Sopenharmony_ci 34780d163575Sopenharmony_ci#define MAX_SIZE 1024 34790d163575Sopenharmony_civoid tcp_access(int sockfd) 34800d163575Sopenharmony_ci{ 34810d163575Sopenharmony_ci size_t n, i; 34820d163575Sopenharmony_ci ssize_t ret; 34830d163575Sopenharmony_ci char msg[MAX_SIZE] = {0}; 34840d163575Sopenharmony_ci while (1) { 34850d163575Sopenharmony_ci PRINTK("waiting for recv\n"); 34860d163575Sopenharmony_ci (void)memset_s(msg, MAX_SIZE, 0, MAX_SIZE); 34870d163575Sopenharmony_ci ret = recv(sockfd, msg, MAX_SIZE - 1, 0); 34880d163575Sopenharmony_ci if (ret < 0) { 34890d163575Sopenharmony_ci PRINTK("recv failed, %d.\n", (u32_t)ret); 34900d163575Sopenharmony_ci (void)closesocket(sockfd); 34910d163575Sopenharmony_ci return; 34920d163575Sopenharmony_ci } else if (ret == 0) { 34930d163575Sopenharmony_ci (void)closesocket(sockfd); 34940d163575Sopenharmony_ci PRINTK("client disconnect.\n"); 34950d163575Sopenharmony_ci return; 34960d163575Sopenharmony_ci } 34970d163575Sopenharmony_ci 34980d163575Sopenharmony_ci n = strlen(msg); 34990d163575Sopenharmony_ci for (i = 0; i < n; ++i) { 35000d163575Sopenharmony_ci if (msg[i] >= 'a' && msg[i] <= 'z') { 35010d163575Sopenharmony_ci msg[i] = (char)(msg[i] + ('A' - 'a')); 35020d163575Sopenharmony_ci } else if (msg[i] >= 'A' && msg[i] <= 'Z') { 35030d163575Sopenharmony_ci msg[i] = (char)(msg[i] + ('a' - 'A')); 35040d163575Sopenharmony_ci } 35050d163575Sopenharmony_ci } 35060d163575Sopenharmony_ci 35070d163575Sopenharmony_ci if (send(sockfd, msg, n, 0) < 0) { 35080d163575Sopenharmony_ci PRINTK("send failed!\r\n"); 35090d163575Sopenharmony_ci continue; 35100d163575Sopenharmony_ci } 35110d163575Sopenharmony_ci } 35120d163575Sopenharmony_ci} 35130d163575Sopenharmony_ci 35140d163575Sopenharmony_ciu32_t osTcpserver(int argc, const char **argv) 35150d163575Sopenharmony_ci{ 35160d163575Sopenharmony_ci uint16_t port; 35170d163575Sopenharmony_ci int sockfd = -1; 35180d163575Sopenharmony_ci int ret; 35190d163575Sopenharmony_ci struct sockaddr_in seraddr; 35200d163575Sopenharmony_ci struct sockaddr_in cliaddr; 35210d163575Sopenharmony_ci u32_t cliaddr_size = (u32_t)sizeof(cliaddr); 35220d163575Sopenharmony_ci int reuse, iPortVal; 35230d163575Sopenharmony_ci 35240d163575Sopenharmony_ci if (tcpip_init_finish == 0) { 35250d163575Sopenharmony_ci PRINTK("tcpip_init have not been called\n"); 35260d163575Sopenharmony_ci return LOS_NOK; 35270d163575Sopenharmony_ci } 35280d163575Sopenharmony_ci 35290d163575Sopenharmony_ci if (argc < 1 || argv == NULL) { 35300d163575Sopenharmony_ci PRINTK("\nUsage: tcpserver <port>\n"); 35310d163575Sopenharmony_ci return LOS_NOK; 35320d163575Sopenharmony_ci } 35330d163575Sopenharmony_ci 35340d163575Sopenharmony_ci iPortVal = atoi(argv[0]); 35350d163575Sopenharmony_ci /* Port 0 not supported , negative values not supported , max port limit is 65535 */ 35360d163575Sopenharmony_ci if (iPortVal <= 0 || iPortVal > 65535) { 35370d163575Sopenharmony_ci PRINTK("\nUsage: Invalid port\n"); 35380d163575Sopenharmony_ci return LOS_NOK; 35390d163575Sopenharmony_ci } 35400d163575Sopenharmony_ci 35410d163575Sopenharmony_ci port = (uint16_t)iPortVal; 35420d163575Sopenharmony_ci 35430d163575Sopenharmony_ci /* removed the print of argv[1] as its accessing argv[1] without verifying argc and 35440d163575Sopenharmony_ci * argv[1] not used anywhere else */ 35450d163575Sopenharmony_ci PRINTK("argv[0]:%s, argc:%d\r\n", argv[0], argc); 35460d163575Sopenharmony_ci sockfd = socket(AF_INET, SOCK_STREAM, 0); 35470d163575Sopenharmony_ci if (sockfd < 0) { 35480d163575Sopenharmony_ci PRINTK("\nUsage: create socket fail!\n"); 35490d163575Sopenharmony_ci return LOS_NOK; 35500d163575Sopenharmony_ci } 35510d163575Sopenharmony_ci reuse = 1; 35520d163575Sopenharmony_ci if (setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, (const char *)&reuse, sizeof(reuse)) != 0) { 35530d163575Sopenharmony_ci (void)closesocket(sockfd); 35540d163575Sopenharmony_ci PRINTK("set SO_REUSEADDR failed\n"); 35550d163575Sopenharmony_ci return LOS_NOK; 35560d163575Sopenharmony_ci } 35570d163575Sopenharmony_ci 35580d163575Sopenharmony_ci (void)memset_s(&seraddr, sizeof(seraddr), 0, sizeof(seraddr)); 35590d163575Sopenharmony_ci seraddr.sin_family = AF_INET; 35600d163575Sopenharmony_ci seraddr.sin_addr.s_addr = htonl(INADDR_ANY); 35610d163575Sopenharmony_ci seraddr.sin_port = htons(port); 35620d163575Sopenharmony_ci 35630d163575Sopenharmony_ci ret = bind(sockfd, (struct sockaddr *)&seraddr, sizeof(seraddr)); 35640d163575Sopenharmony_ci if (ret < 0) { 35650d163575Sopenharmony_ci PRINTK("bind ip and port failed"); 35660d163575Sopenharmony_ci (void)closesocket(sockfd); 35670d163575Sopenharmony_ci return LOS_NOK; 35680d163575Sopenharmony_ci } 35690d163575Sopenharmony_ci 35700d163575Sopenharmony_ci ret = listen(sockfd, 5); 35710d163575Sopenharmony_ci if (ret < 0) { 35720d163575Sopenharmony_ci (void)closesocket(sockfd); 35730d163575Sopenharmony_ci PRINTK("listen failed\n"); 35740d163575Sopenharmony_ci return LOS_NOK; 35750d163575Sopenharmony_ci } 35760d163575Sopenharmony_ci while (1) { 35770d163575Sopenharmony_ci PRINTK("waiting for accept\n"); 35780d163575Sopenharmony_ci (void)memset_s(&cliaddr, sizeof(struct sockaddr_in), 0, sizeof(struct sockaddr_in)); 35790d163575Sopenharmony_ci ret = (int)accept(sockfd, (struct sockaddr *)&cliaddr, &cliaddr_size); 35800d163575Sopenharmony_ci if (ret < 0) { 35810d163575Sopenharmony_ci (void)closesocket(sockfd); 35820d163575Sopenharmony_ci PRINTK("Accept failed, %d\n", ret); 35830d163575Sopenharmony_ci break; 35840d163575Sopenharmony_ci } 35850d163575Sopenharmony_ci tcp_access(ret); 35860d163575Sopenharmony_ci } 35870d163575Sopenharmony_ci return LOS_NOK; // Hits Only If Accept Fails 35880d163575Sopenharmony_ci} 35890d163575Sopenharmony_ci 35900d163575Sopenharmony_ci#ifdef LOSCFG_SHELL_CMD_DEBUG 35910d163575Sopenharmony_ciSHELLCMD_ENTRY(tcpserver_shellcmd, CMD_TYPE_EX, "tcpserver", XARGS, (CmdCallBackFunc)osTcpserver); 35920d163575Sopenharmony_ci#endif /* LOSCFG_SHELL_CMD_DEBUG */ 35930d163575Sopenharmony_ci#endif /* LWIP_DEBUG_TCPSERVER */ 35940d163575Sopenharmony_ci 35950d163575Sopenharmony_ci#ifdef LWIP_DEBUG_UDPSERVER 35960d163575Sopenharmony_civoid udpserver(int argc, const char **argv) 35970d163575Sopenharmony_ci{ 35980d163575Sopenharmony_ci int sockfd, fromlen; 35990d163575Sopenharmony_ci int ret, iPortVal; 36000d163575Sopenharmony_ci struct sockaddr_in seraddr; 36010d163575Sopenharmony_ci struct sockaddr_in cliaddr; 36020d163575Sopenharmony_ci size_t n, i; 36030d163575Sopenharmony_ci 36040d163575Sopenharmony_ci char msg[MAX_SIZE] = {0}; 36050d163575Sopenharmony_ci uint16_t port; 36060d163575Sopenharmony_ci 36070d163575Sopenharmony_ci if (argc < 1) { 36080d163575Sopenharmony_ci PRINTK("\nUsage: udpserver <port>\n"); 36090d163575Sopenharmony_ci return; 36100d163575Sopenharmony_ci } 36110d163575Sopenharmony_ci 36120d163575Sopenharmony_ci iPortVal = atoi(argv[0]); 36130d163575Sopenharmony_ci /* Port 0 not supported , negative values not supported , max port limit is 65535 */ 36140d163575Sopenharmony_ci if (iPortVal <= 0 || iPortVal > 65535) { 36150d163575Sopenharmony_ci PRINTK("\nUsage: Invalid Port\n"); 36160d163575Sopenharmony_ci return; 36170d163575Sopenharmony_ci } 36180d163575Sopenharmony_ci 36190d163575Sopenharmony_ci port = (uint16_t)iPortVal; 36200d163575Sopenharmony_ci 36210d163575Sopenharmony_ci PRINTK("port:%d\r\n", port); 36220d163575Sopenharmony_ci 36230d163575Sopenharmony_ci sockfd = lwip_socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP); 36240d163575Sopenharmony_ci if (sockfd == -1) { 36250d163575Sopenharmony_ci PRINTK("\ncreate socket fail\n"); 36260d163575Sopenharmony_ci return; 36270d163575Sopenharmony_ci } 36280d163575Sopenharmony_ci 36290d163575Sopenharmony_ci (void)memset_s(&seraddr, sizeof(seraddr), 0, sizeof(seraddr)); 36300d163575Sopenharmony_ci (void)memset_s(&cliaddr, sizeof(cliaddr), 0, sizeof(cliaddr)); 36310d163575Sopenharmony_ci seraddr.sin_family = AF_INET; 36320d163575Sopenharmony_ci seraddr.sin_addr.s_addr = htonl(INADDR_ANY); 36330d163575Sopenharmony_ci seraddr.sin_port = htons(port); 36340d163575Sopenharmony_ci ret = lwip_bind(sockfd, (struct sockaddr *)&seraddr, sizeof(seraddr)); 36350d163575Sopenharmony_ci if (ret < 0) { 36360d163575Sopenharmony_ci PRINTK("bind ip and port failed:%d\n", errno); 36370d163575Sopenharmony_ci (void)closesocket(sockfd); 36380d163575Sopenharmony_ci return; 36390d163575Sopenharmony_ci } 36400d163575Sopenharmony_ci 36410d163575Sopenharmony_ci while (1) { 36420d163575Sopenharmony_ci ret = recvfrom(sockfd, msg, MAX_SIZE - 1, 0, (struct sockaddr *)&cliaddr, (socklen_t *)&fromlen); 36430d163575Sopenharmony_ci if (ret >= 0) { 36440d163575Sopenharmony_ci n = strlen(msg); 36450d163575Sopenharmony_ci for (i = 0; i < n; ++i) { 36460d163575Sopenharmony_ci if (msg[i] >= 'a' && msg[i] <= 'z') { 36470d163575Sopenharmony_ci msg[i] = (char)(msg[i] + 'A' - 'a'); 36480d163575Sopenharmony_ci } else if (msg[i] >= 'A' && msg[i] <= 'Z') { 36490d163575Sopenharmony_ci msg[i] = (char)(msg[i] + 'a' - 'A'); 36500d163575Sopenharmony_ci } 36510d163575Sopenharmony_ci } 36520d163575Sopenharmony_ci ret = sendto(sockfd, msg, n + 1, 0, (struct sockaddr *)&cliaddr, (socklen_t)fromlen); 36530d163575Sopenharmony_ci if (ret <= 0 && errno == EPIPE) { 36540d163575Sopenharmony_ci break; 36550d163575Sopenharmony_ci } 36560d163575Sopenharmony_ci } else { 36570d163575Sopenharmony_ci break; 36580d163575Sopenharmony_ci } 36590d163575Sopenharmony_ci } 36600d163575Sopenharmony_ci 36610d163575Sopenharmony_ci (void)closesocket(sockfd); 36620d163575Sopenharmony_ci return; 36630d163575Sopenharmony_ci} 36640d163575Sopenharmony_ci 36650d163575Sopenharmony_ci#ifdef LOSCFG_SHELL_CMD_DEBUG 36660d163575Sopenharmony_ciSHELLCMD_ENTRY(udpserver_shellcmd, CMD_TYPE_EX, "udpserver", XARGS, (CmdCallBackFunc)udpserver); 36670d163575Sopenharmony_ci#endif /* LOSCFG_SHELL_CMD_DEBUG */ 36680d163575Sopenharmony_ci#endif /* LWIP_DEBUG_UDPSERVER */ 36690d163575Sopenharmony_ci 36700d163575Sopenharmony_ci#ifdef LWIP_DEBUG_INFO 36710d163575Sopenharmony_ciLWIP_STATIC 36720d163575Sopenharmony_ciu32_t netdebug_memp(int argc, const char **argv) 36730d163575Sopenharmony_ci{ 36740d163575Sopenharmony_ci u32_t ret = LOS_OK; 36750d163575Sopenharmony_ci int type; 36760d163575Sopenharmony_ci 36770d163575Sopenharmony_ci if (argc == 2) { 36780d163575Sopenharmony_ci if (!strcmp("-i", argv[1])) { 36790d163575Sopenharmony_ci debug_memp_info(); 36800d163575Sopenharmony_ci } else if (!strcmp("-udp", argv[1])) { 36810d163575Sopenharmony_ci debug_memp_type_info(MEMP_UDP_PCB); 36820d163575Sopenharmony_ci } else if (!strcmp("-tcp", argv[1])) { 36830d163575Sopenharmony_ci debug_memp_type_info(MEMP_TCP_PCB); 36840d163575Sopenharmony_ci } else if (!strcmp("-raw", argv[1])) { 36850d163575Sopenharmony_ci debug_memp_type_info(MEMP_RAW_PCB); 36860d163575Sopenharmony_ci } else if (!strcmp("-conn", argv[1])) { 36870d163575Sopenharmony_ci debug_memp_type_info(MEMP_NETCONN); 36880d163575Sopenharmony_ci } else { 36890d163575Sopenharmony_ci ret = LOS_NOK; 36900d163575Sopenharmony_ci } 36910d163575Sopenharmony_ci } else if (argc == 3) { 36920d163575Sopenharmony_ci if (!strcmp("-d", argv[1])) { 36930d163575Sopenharmony_ci type = atoi(argv[2]); 36940d163575Sopenharmony_ci if (type >= 0) { 36950d163575Sopenharmony_ci debug_memp_detail(type); 36960d163575Sopenharmony_ci } else { 36970d163575Sopenharmony_ci PRINTK("Error: type < 0\n"); 36980d163575Sopenharmony_ci ret = LOS_NOK; 36990d163575Sopenharmony_ci } 37000d163575Sopenharmony_ci } else { 37010d163575Sopenharmony_ci ret = LOS_NOK; 37020d163575Sopenharmony_ci } 37030d163575Sopenharmony_ci } else { 37040d163575Sopenharmony_ci ret = LOS_NOK; 37050d163575Sopenharmony_ci } 37060d163575Sopenharmony_ci 37070d163575Sopenharmony_ci return ret; 37080d163575Sopenharmony_ci} 37090d163575Sopenharmony_ci 37100d163575Sopenharmony_ciLWIP_STATIC 37110d163575Sopenharmony_ciu32_t netdebug_sock(int argc, const char **argv) 37120d163575Sopenharmony_ci{ 37130d163575Sopenharmony_ci int idx; 37140d163575Sopenharmony_ci u32_t ret = LOS_NOK; 37150d163575Sopenharmony_ci 37160d163575Sopenharmony_ci if (argc == 2) { /* 2: Number of command parameters */ 37170d163575Sopenharmony_ci if (!strcmp("-i", argv[1])) { 37180d163575Sopenharmony_ci /* netdebug sock -i */ 37190d163575Sopenharmony_ci for (idx = 0; idx < (int)LWIP_CONFIG_NUM_SOCKETS; idx++) { 37200d163575Sopenharmony_ci debug_socket_info(idx, 1, 0); 37210d163575Sopenharmony_ci } 37220d163575Sopenharmony_ci ret = LOS_OK; 37230d163575Sopenharmony_ci } 37240d163575Sopenharmony_ci } else if (argc == 3) { /* 3: Number of command parameters */ 37250d163575Sopenharmony_ci if (!strcmp("-d", argv[1])) { 37260d163575Sopenharmony_ci idx = atoi(argv[2]); /* 2: netdebug sock -d <idx> */ 37270d163575Sopenharmony_ci if (idx >= 0) { 37280d163575Sopenharmony_ci debug_socket_info(idx, 1, 1); 37290d163575Sopenharmony_ci ret = LOS_OK; 37300d163575Sopenharmony_ci } else { 37310d163575Sopenharmony_ci PRINTK("Error: idx < 0\n"); 37320d163575Sopenharmony_ci } 37330d163575Sopenharmony_ci } 37340d163575Sopenharmony_ci } 37350d163575Sopenharmony_ci 37360d163575Sopenharmony_ci return ret; 37370d163575Sopenharmony_ci} 37380d163575Sopenharmony_ci 37390d163575Sopenharmony_ci 37400d163575Sopenharmony_ciu32_t osShellNetDebug(int argc, const char **argv) 37410d163575Sopenharmony_ci{ 37420d163575Sopenharmony_ci u32_t ret = LOS_NOK; 37430d163575Sopenharmony_ci 37440d163575Sopenharmony_ci if (argc < 1 || argv == NULL) { 37450d163575Sopenharmony_ci goto usage; 37460d163575Sopenharmony_ci } 37470d163575Sopenharmony_ci 37480d163575Sopenharmony_ci if (!strcmp("memp", argv[0])) { 37490d163575Sopenharmony_ci ret = netdebug_memp(argc, argv); 37500d163575Sopenharmony_ci if (ret != LOS_OK) { 37510d163575Sopenharmony_ci goto usage_memp; 37520d163575Sopenharmony_ci } 37530d163575Sopenharmony_ci } else if (!strcmp("sock", argv[0])) { 37540d163575Sopenharmony_ci /* netdebug sock {-i | -d <idx>} */ 37550d163575Sopenharmony_ci ret = netdebug_sock(argc, argv); 37560d163575Sopenharmony_ci if (ret != LOS_OK) { 37570d163575Sopenharmony_ci goto usage_sock; 37580d163575Sopenharmony_ci } 37590d163575Sopenharmony_ci } else { 37600d163575Sopenharmony_ci goto usage; 37610d163575Sopenharmony_ci } 37620d163575Sopenharmony_ci return ret; 37630d163575Sopenharmony_ci 37640d163575Sopenharmony_ciusage: 37650d163575Sopenharmony_ci /* Cmd help */ 37660d163575Sopenharmony_ci PRINTK("\nUsage:\n"); 37670d163575Sopenharmony_ci PRINTK("netdebug memp {-i | -d <type> | -udp | -tcp | -raw |-conn}\n"); 37680d163575Sopenharmony_ci PRINTK("netdebug sock {-i | -d <idx>}\n"); 37690d163575Sopenharmony_ci return LOS_NOK; 37700d163575Sopenharmony_ci 37710d163575Sopenharmony_ciusage_memp: 37720d163575Sopenharmony_ci /* netdebug memp help */ 37730d163575Sopenharmony_ci PRINTK("\nUsage:\n"); 37740d163575Sopenharmony_ci PRINTK("netdebug memp {-i | -d <type> | -udp | -tcp | -raw |-conn}\n"); 37750d163575Sopenharmony_ci return LOS_NOK; 37760d163575Sopenharmony_ci 37770d163575Sopenharmony_ciusage_sock: 37780d163575Sopenharmony_ci /* netdebug sock help */ 37790d163575Sopenharmony_ci PRINTK("\nUsage:\n"); 37800d163575Sopenharmony_ci PRINTK("netdebug sock {-i | -d <idx>}\n"); 37810d163575Sopenharmony_ci return LOS_NOK; 37820d163575Sopenharmony_ci} 37830d163575Sopenharmony_ci#endif /* LWIP_DEBUG_INFO */ 37840d163575Sopenharmony_ci 37850d163575Sopenharmony_ci#if defined(LOSCFG_SHELL_CMD_DEBUG) && defined(LWIP_DEBUG_INFO) 37860d163575Sopenharmony_ciSHELLCMD_ENTRY(netdebug_shellcmd, CMD_TYPE_EX, "netdebug", XARGS, (CmdCallBackFunc)osShellNetDebug); 37870d163575Sopenharmony_ci#endif /* LOSCFG_SHELL_CMD_DEBUG && LWIP_DEBUG_INFO */ 37880d163575Sopenharmony_ci 37890d163575Sopenharmony_ciu32_t osShellIpDebug(int argc, const char **argv) 37900d163575Sopenharmony_ci{ 37910d163575Sopenharmony_ci u8_t i = 0; 37920d163575Sopenharmony_ci char acIPv6Addr[IP6ADDR_STRLEN_MAX + 1] = {0}; 37930d163575Sopenharmony_ci char aclladdr[20] = {0}; 37940d163575Sopenharmony_ci const char *acStates[] = {"NO_ENTRY", "INCOMPLETE", "REACHABLE", "STALE", "DELAY", "PROBE"}; 37950d163575Sopenharmony_ci u8_t atleastOneEntry = 0; 37960d163575Sopenharmony_ci 37970d163575Sopenharmony_ci if (!tcpip_init_finish) { 37980d163575Sopenharmony_ci PRINTK("%s: tcpip_init have not been called\n", __FUNCTION__); 37990d163575Sopenharmony_ci goto exit; 38000d163575Sopenharmony_ci } 38010d163575Sopenharmony_ci 38020d163575Sopenharmony_ci /* Display prefix */ 38030d163575Sopenharmony_ci PRINTK("=================\n"); 38040d163575Sopenharmony_ci PRINTK("|| Prefix List ||\n"); 38050d163575Sopenharmony_ci PRINTK("=================\n"); 38060d163575Sopenharmony_ci PRINTK("%-50s %-16s %-20s\n", "Prefix", "netif", "validLifetime"); 38070d163575Sopenharmony_ci PRINTK("---------------------------------------------------------------------------------\n"); 38080d163575Sopenharmony_ci /* Display neighbour Cache Entry */ 38090d163575Sopenharmony_ci for (i = 0; i < LWIP_ND6_NUM_PREFIXES; i++) { 38100d163575Sopenharmony_ci if (prefix_list[i].netif != NULL && prefix_list[i].invalidation_timer > 0) { 38110d163575Sopenharmony_ci atleastOneEntry = 1; 38120d163575Sopenharmony_ci (void)ip6addr_ntoa_r((const ip6_addr_t *)(prefix_list[i].prefix.addr), (acIPv6Addr), sizeof(acIPv6Addr)); 38130d163575Sopenharmony_ci PRINTK("%-50s ", acIPv6Addr); 38140d163575Sopenharmony_ci PRINTK("%-16s ", netif_get_name(prefix_list[i].netif)); 38150d163575Sopenharmony_ci PRINTK("%-20u\n", prefix_list[i].invalidation_timer); 38160d163575Sopenharmony_ci } 38170d163575Sopenharmony_ci } 38180d163575Sopenharmony_ci 38190d163575Sopenharmony_ci if (!atleastOneEntry) { 38200d163575Sopenharmony_ci PRINTK("**** NO VALID PREFIXES FOUND CONFIGURED ****\n"); 38210d163575Sopenharmony_ci } 38220d163575Sopenharmony_ci PRINTK("---------------------------------------------------------------------------------\n"); 38230d163575Sopenharmony_ci 38240d163575Sopenharmony_ci atleastOneEntry = 0; 38250d163575Sopenharmony_ci 38260d163575Sopenharmony_ci PRINTK("\n\n"); 38270d163575Sopenharmony_ci PRINTK("============================\n"); 38280d163575Sopenharmony_ci PRINTK("|| Neighbor Cache Entries ||\n"); 38290d163575Sopenharmony_ci PRINTK("============================\n"); 38300d163575Sopenharmony_ci PRINTK("%-50s %-25s %-16s %-15s %-10s\n", "Neighbor", "MAC", "netif", "state", "IsRouter"); 38310d163575Sopenharmony_ci PRINTK("------------------------------------------------------------" 38320d163575Sopenharmony_ci "----------------------------------------------------------\n"); 38330d163575Sopenharmony_ci 38340d163575Sopenharmony_ci /* Display neighbour Cache Entry */ 38350d163575Sopenharmony_ci for (i = 0; i < LWIP_ND6_NUM_NEIGHBORS; i++) { 38360d163575Sopenharmony_ci if (neighbor_cache[i].state != ND6_NO_ENTRY) { 38370d163575Sopenharmony_ci atleastOneEntry = 1; 38380d163575Sopenharmony_ci (void)ip6addr_ntoa_r((const ip6_addr_t *)(neighbor_cache[i].next_hop_address.addr), (acIPv6Addr), 38390d163575Sopenharmony_ci sizeof(acIPv6Addr)); 38400d163575Sopenharmony_ci PRINTK("%-50s ", acIPv6Addr); 38410d163575Sopenharmony_ci 38420d163575Sopenharmony_ci if (snprintf_s(aclladdr, sizeof(aclladdr), sizeof(aclladdr) - 1, "%02X:%02X:%02X:%02X:%02X:%02X", 38430d163575Sopenharmony_ci neighbor_cache[i].lladdr[0], neighbor_cache[i].lladdr[1], /* 0, 1, member number */ 38440d163575Sopenharmony_ci neighbor_cache[i].lladdr[2], neighbor_cache[i].lladdr[3], /* 2, 3, member number */ 38450d163575Sopenharmony_ci neighbor_cache[i].lladdr[4], neighbor_cache[i].lladdr[5]) < 0) { /* 4, 5, member number */ 38460d163575Sopenharmony_ci return LOS_NOK; 38470d163575Sopenharmony_ci } 38480d163575Sopenharmony_ci PRINTK("%-25s ", aclladdr); 38490d163575Sopenharmony_ci PRINTK("%-16s ", netif_get_name(neighbor_cache[i].netif)); 38500d163575Sopenharmony_ci PRINTK("%-15s ", acStates[neighbor_cache[i].state]); 38510d163575Sopenharmony_ci PRINTK("%-10s\n", (neighbor_cache[i].isrouter ? "Yes" : "No")); 38520d163575Sopenharmony_ci } 38530d163575Sopenharmony_ci } 38540d163575Sopenharmony_ci if (!atleastOneEntry) { 38550d163575Sopenharmony_ci PRINTK("**** NO NEIGHBOURS FOUND ****\n"); 38560d163575Sopenharmony_ci } 38570d163575Sopenharmony_ci PRINTK("------------------------------------------------------------" 38580d163575Sopenharmony_ci "----------------------------------------------------------\n"); 38590d163575Sopenharmony_ci 38600d163575Sopenharmony_ci atleastOneEntry = 0; 38610d163575Sopenharmony_ci 38620d163575Sopenharmony_ci PRINTK("\n\n"); 38630d163575Sopenharmony_ci PRINTK("===============================\n"); 38640d163575Sopenharmony_ci PRINTK("|| Destination Cache Entries ||\n"); 38650d163575Sopenharmony_ci PRINTK("===============================\n"); 38660d163575Sopenharmony_ci PRINTK("%-50s %-50s %-10s %-10s\n", "Destination", "NextHop", "PMTU", "age"); 38670d163575Sopenharmony_ci PRINTK("------------------------------------------------------------" 38680d163575Sopenharmony_ci "--------------------------------------------------------\n"); 38690d163575Sopenharmony_ci /* Display destination Cache Entry */ 38700d163575Sopenharmony_ci for (i = 0; i < LWIP_ND6_NUM_DESTINATIONS; i++) { 38710d163575Sopenharmony_ci if (!ip6_addr_isany(&(destination_cache[i].destination_addr))) { 38720d163575Sopenharmony_ci atleastOneEntry = 1; 38730d163575Sopenharmony_ci (void)ip6addr_ntoa_r((const ip6_addr_t *)(destination_cache[i].destination_addr.addr), (acIPv6Addr), 38740d163575Sopenharmony_ci sizeof(acIPv6Addr)); 38750d163575Sopenharmony_ci PRINTK("%-50s ", acIPv6Addr); 38760d163575Sopenharmony_ci (void)ip6addr_ntoa_r((const ip6_addr_t *)(destination_cache[i].next_hop_addr.addr), (acIPv6Addr), 38770d163575Sopenharmony_ci sizeof(acIPv6Addr)); 38780d163575Sopenharmony_ci PRINTK("%-50s ", acIPv6Addr); 38790d163575Sopenharmony_ci PRINTK("%-10u ", destination_cache[i].pmtu); 38800d163575Sopenharmony_ci PRINTK("%-10u\n", destination_cache[i].age); 38810d163575Sopenharmony_ci } 38820d163575Sopenharmony_ci } 38830d163575Sopenharmony_ci if (!atleastOneEntry) { 38840d163575Sopenharmony_ci PRINTK("**** NO DESTINATION CACHE FOUND ****\n"); 38850d163575Sopenharmony_ci } 38860d163575Sopenharmony_ci PRINTK("------------------------------------------------------------" 38870d163575Sopenharmony_ci "--------------------------------------------------------\n"); 38880d163575Sopenharmony_ci 38890d163575Sopenharmony_ci atleastOneEntry = 0; 38900d163575Sopenharmony_ci PRINTK("\n\n"); 38910d163575Sopenharmony_ci PRINTK("============================\n"); 38920d163575Sopenharmony_ci PRINTK("|| Default Router Entries ||\n"); 38930d163575Sopenharmony_ci PRINTK("============================\n"); 38940d163575Sopenharmony_ci PRINTK("%-50s %-20s %-10s\n", "Router", "invalidation_timer", "flags"); 38950d163575Sopenharmony_ci PRINTK("-----------------------------------------------------------------------------\n"); 38960d163575Sopenharmony_ci /* Display Default Router Cache Entry */ 38970d163575Sopenharmony_ci for (i = 0; i < LWIP_ND6_NUM_ROUTERS; i++) { 38980d163575Sopenharmony_ci if (default_router_list[i].neighbor_entry) { 38990d163575Sopenharmony_ci atleastOneEntry = 1; 39000d163575Sopenharmony_ci (void)ip6addr_ntoa_r((const ip6_addr_t *)((default_router_list[i].neighbor_entry)->next_hop_address.addr), 39010d163575Sopenharmony_ci (acIPv6Addr), sizeof(acIPv6Addr)); 39020d163575Sopenharmony_ci PRINTK("%-50s ", acIPv6Addr); 39030d163575Sopenharmony_ci PRINTK("%-20u ", default_router_list[i].invalidation_timer); 39040d163575Sopenharmony_ci PRINTK("%-10u\n", default_router_list[i].flags); 39050d163575Sopenharmony_ci } 39060d163575Sopenharmony_ci } 39070d163575Sopenharmony_ci if (!atleastOneEntry) { 39080d163575Sopenharmony_ci PRINTK("**** NO DEFAULT ROUTERS FOUND ****\n"); 39090d163575Sopenharmony_ci } 39100d163575Sopenharmony_ci PRINTK("-----------------------------------------------------------------------------\n"); 39110d163575Sopenharmony_ci 39120d163575Sopenharmony_ciexit: 39130d163575Sopenharmony_ci return LOS_OK; 39140d163575Sopenharmony_ci} 39150d163575Sopenharmony_ci 39160d163575Sopenharmony_ci#ifdef LOSCFG_SHELL_CMD_DEBUG 39170d163575Sopenharmony_ciSHELLCMD_ENTRY(ipdebug_shellcmd, CMD_TYPE_EX, "ipdebug", XARGS, (CmdCallBackFunc)osShellIpDebug); 39180d163575Sopenharmony_ci#endif 39190d163575Sopenharmony_ci#ifdef LWIP_TESTBED 39200d163575Sopenharmony_ciextern void cmd_reset(void); 39210d163575Sopenharmony_ci 39220d163575Sopenharmony_civoid osShellReboot(int argc, const char **argv) 39230d163575Sopenharmony_ci{ 39240d163575Sopenharmony_ci cmd_reset(); 39250d163575Sopenharmony_ci} 39260d163575Sopenharmony_ci 39270d163575Sopenharmony_ci#ifdef LOSCFG_SHELL_CMD_DEBUG 39280d163575Sopenharmony_ciSHELLCMD_ENTRY(reboot_shellcmd, CMD_TYPE_EX, "reboot", XARGS, (CmdCallBackFunc)osShellReboot); 39290d163575Sopenharmony_ci#endif /* LOSCFG_SHELL_CMD_DEBUG */ 39300d163575Sopenharmony_ci#endif 39310d163575Sopenharmony_ci 39320d163575Sopenharmony_ci#endif // LWIP_ENABLE_LOS_SHELL_CMD 3933