/*
* Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved.
* Copyright (c) 2020-2022 Huawei Device Co., Ltd. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this list of
* conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice, this list
* of conditions and the following disclaimer in the documentation and/or other materials
* provided with the distribution.
*
* 3. Neither the name of the copyright holder nor the names of its contributors may be used
* to endorse or promote products derived from this software without specific prior written
* permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "../core/ipv4/etharp.c" /* for arp_table */
#define icmp6_hdr netinet_icmp6_hdr
#include <netinet/icmp6.h>
#undef icmp6_hdr
#include "lwip/fixme.h"
#include "lwip/opt.h"
#if LWIP_ENABLE_LOS_SHELL_CMD
#include "lwip/api.h"
#include "lwip/tcpip.h"
#include "lwip/netif.h"
#include "lwip/netdb.h"
#include "lwip/stats.h"
#include "lwip/err.h"
#include "lwip/inet.h"
#include "netif/etharp.h"
#include "lwip/ip_addr.h"
#include "lwip/ip6_addr.h"
#include "lwip/icmp.h"
#include "lwip/priv/nd6_priv.h"
#include "lwip/sockets.h"
#include "lwip/inet_chksum.h"
#include "lwip/raw.h"
#include "los_config.h"
#include <string.h>
#include "limits.h"
#include <stdlib.h>
#include <stdio.h>
#include <errno.h>
#include <time.h>
#include <ctype.h>
#include <poll.h>
#include "lwip/api_shell.h"
#include "lwip/dns.h"
#include "lwip/udp.h"
#include "lwip/priv/tcp_priv.h"
#include "lwip/dhcp.h"
#include "lwip/netifapi.h"
#include "los_strnlen_user.h"
#include "linux/kernel.h"
#ifdef LOSCFG_SHELL
#include "shcmd.h"
#include "shell.h"
#endif
#define LWIP_STATIC static
#if LWIP_ARP
extern sys_sem_t ip_conflict_detect;
#endif
extern volatile int tcpip_init_finish;
extern const char *const tcp_state_str[];
extern int get_unused_socket_num(void);
#if LWIP_IPV6
#define LWIP_MAX_PING6_ARG_COUNT 64
#define LWIP_PING6_STANDARD_PKT_SIZE 56
#define LWIP_PING6_STARTING_SEQ_NUM 0x2255
#define LWIP_PING6_OUT_OF_ORDER_MAGNITUDE 1
#define LWIP_PING6_COUNT_ARG 1
#define LWIP_PING6_SOURCE_ADDRESS_ARG 2
#define LWIP_PING6_INTERFACE_ARG 4
#define LWIP_PING6_HOSTNAME_ARG 8
#define LWIP_PING6_DEFAULT_SOCKET 16
#endif
/* Forward Declarations [START] */
#ifndef LWIP_TESTBED
LWIP_STATIC
#endif
int print_netif(struct netif *netif, char *print_buf, unsigned int buf_len);
#ifndef LWIP_TESTBED
LWIP_STATIC
#endif
void lwip_ifconfig_show_internal(void *arg);
#ifndef LWIP_TESTBED
LWIP_STATIC
#endif
void lwip_ifconfig_internal(void *arg);
void lwip_printsize(size_t size);
LWIP_STATIC void lwip_ifconfig_usage(const char *cmd);
#ifndef LWIP_TESTBED
LWIP_STATIC
#endif
void lwip_arp_show_internal(struct netif *netif, char *printf_buf, unsigned int buf_len);
#ifndef LWIP_TESTBED
LWIP_STATIC
#endif
void lwip_arp_internal(void *arg);
LWIP_STATIC void lwip_arp_usage(const char *cmd);
void ifup_internal(void *arg);
void ifdown_internal(void *arg);
#if LWIP_DNS
LWIP_STATIC unsigned int get_hostip(const char *hname);
#ifndef LWIP_TESTBED
LWIP_STATIC
#endif
struct hostent *gethostnameinfo(const char *host);
#endif /* LWIP_DNS */
#ifdef LWIP_DEBUG_INFO
LWIP_STATIC u32_t netdebug_memp(int argc, const char **argv);
LWIP_STATIC u32_t netdebug_sock(int argc, const char **argv);
u32_t osShellNetDebug(int argc, const char **argv);
u32_t osShellIpDebug(int argc, const char **argv);
#endif /* LWIP_DEBUG_INFO */
#if LWIP_IPV6
/* Holds params for ping6 task */
typedef struct ping6_args {
u8_t args_found;
u8_t interface_index;
u8_t host_index;
u8_t pad;
u32_t pingcount;
ip6_addr_t src_addr;
ip6_addr_t dst_addr;
} ping6_args_t;
/* Holds stats for ongoing ping6 task */
typedef struct ping6_stats {
u32_t flag;
u32_t min_rtt;
u32_t max_rtt;
float avg_rtt;
} ping6_stats_t;
LWIP_STATIC void update_ping6_stats(ping6_stats_t *ping6_stats, u32_t rtt, u32_t nreceived);
LWIP_STATIC int parse_args_ping6(int argc, const char **argv, ping6_args_t *ping6_params);
u32_t osShellPing6(int argc, const char **argv);
LWIP_STATIC int create_ping6_socket(u8_t type, const void *param);
LWIP_STATIC const char *convert_icmpv6_err_to_string(u8_t err_type);
#endif /* LWIP_IPV6 */
u32_t osTcpserver(int argc, const char **argv);
void udpserver(int argc, const char **argv);
void tcp_access(int sockfd);
#if LWIP_IPV6
int netstat_get_udp_sendQLen6(struct udp_pcb *udppcb, struct pbuf *udpbuf);
int netstat_udp_sendq6(struct udp_pcb *upcb);
#endif
#if LWIP_IPV4
int netstat_get_udp_sendQLen(struct udp_pcb *udppcb, struct pbuf *udpbuf);
#endif
int netstat_tcp_sendq(struct tcp_pcb *tpcb);
int netstat_tcp_recvq(struct tcp_pcb *tpcb);
int netstat_netconn_recvq(const struct netconn *conn);
int netstat_udp_sendq(struct udp_pcb *upcb);
int netstat_netconn_sendq(struct netconn *conn);
/* Forward Declarations [END] */
#define IFCONFIG_OPTION_SET_IP (1)
#define IFCONFIG_OPTION_SET_NETMASK (1 << 1)
#define IFCONFIG_OPTION_SET_GW (1 << 2)
#define IFCONFIG_OPTION_SET_HW (1 << 3)
#define IFCONFIG_OPTION_SET_UP (1 << 4)
#define IFCONFIG_OPTION_SET_DOWN (1 << 5)
#define IFCONFIG_OPTION_SET_MTU (1 << 6)
#define IFCONFIG_OPTION_DEL_IP (1 << 7)
#define NETSTAT_ENTRY_SIZE 120
#define MAX_NETSTAT_ENTRY (NETSTAT_ENTRY_SIZE * (MEMP_NUM_TCP_PCB + MEMP_NUM_UDP_PCB + MEMP_NUM_TCP_PCB_LISTEN + 1))
#define PRINT_BUF_LEN 1024
#define MAX_MACADDR_STRING_LENGTH 18 /* including NULL */
#define CONVERT_STRING_TO_HEX(_src, _dest) \
{ \
const char *_srcString = (char *)_src; \
_dest = 0; \
while (*_srcString) { \
_dest = (unsigned char)((_dest << 4) & 0xFF); \
if ((*_srcString >= 48) && (*_srcString <= 57)) /* between 0 to 9 */ \
_dest |= (unsigned char)(*_srcString - 48); \
else if ((*_srcString >= 65 && *_srcString <= 70)) /* between A to F */ \
_dest |= (unsigned char)((*_srcString - 65) + 10); \
else if ((*_srcString >= 97 && *_srcString <= 102)) /* between a to f */ \
_dest |= (unsigned char)((*_srcString - 97) + 10); \
else break; \
++_srcString; \
}