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, &ethaddr,
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, &ethaddr);
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