From 0b36be9b983ad944852e776310b8e3282da7b145 Mon Sep 17 00:00:00 2001 From: =?utf8?q?Jakub=20Nejedl=C3=BD?= Date: Wed, 21 Aug 2019 09:56:07 +0200 Subject: [PATCH] Add ping function to debug tools Ping command is now useable to test ethernet conection. Main part of code was taken from http://www.smallerapple.com/ZhangJianfei/rt-thread/blob/98fc1cb4cf0fd20a79f16b72fd72846c207702b5/components/net/lwip-1.3.2/apps/ping.c --- rpp-test-sw/Makefile.var | 1 + rpp-test-sw/commands/.gitattributes | 2 + rpp-test-sw/commands/cmd.c | 2 + rpp-test-sw/commands/cmd_ping.c | 199 ++++++++++++++++++++++++++++ rpp-test-sw/commands/cmd_ping.h | 18 +++ 5 files changed, 222 insertions(+) create mode 100644 rpp-test-sw/commands/cmd_ping.c create mode 100644 rpp-test-sw/commands/cmd_ping.h diff --git a/rpp-test-sw/Makefile.var b/rpp-test-sw/Makefile.var index 841e25f..7b42df3 100644 --- a/rpp-test-sw/Makefile.var +++ b/rpp-test-sw/Makefile.var @@ -17,6 +17,7 @@ SOURCES = \ commands/cmd_nc.c \ commands/cmd_netstats.c \ commands/cmd_echoserver.c \ + commands/cmd_ping.c \ commands/main.c SOURCES_tms570_rpp = \ diff --git a/rpp-test-sw/commands/.gitattributes b/rpp-test-sw/commands/.gitattributes index c0915cf..3b040e8 100644 --- a/rpp-test-sw/commands/.gitattributes +++ b/rpp-test-sw/commands/.gitattributes @@ -14,6 +14,8 @@ /cmd_netstats.h eaton /cmd_pin.c eaton /cmd_pin.h eaton +/cmd_ping.c eaton +/cmd_ping.h eaton /cmd_port.c eaton /cmd_port.h eaton /main.c eaton diff --git a/rpp-test-sw/commands/cmd.c b/rpp-test-sw/commands/cmd.c index 008027a..2937721 100644 --- a/rpp-test-sw/commands/cmd.c +++ b/rpp-test-sw/commands/cmd.c @@ -29,6 +29,7 @@ #include "cmd_netstats.h" #include "cmd_emac.h" #include "cmd_echoserver.h" +#include "cmd_ping.h" #ifdef TARGET_TMS570_RPP #include "cmd_dac.h" @@ -151,6 +152,7 @@ cmd_des_t const *cmd_list_main[] = { CMD_DES_INCLUDE_SUBLIST(cmd_list_nc), CMD_DES_INCLUDE_SUBLIST(cmd_list_es), CMD_DES_INCLUDE_SUBLIST(cmd_list_netstats), + CMD_DES_INCLUDE_SUBLIST(cmd_list_ping), #ifdef TARGET_TMS570_RPP CMD_DES_INCLUDE_SUBLIST(cmd_list_dac), CMD_DES_INCLUDE_SUBLIST(cmd_list_din), diff --git a/rpp-test-sw/commands/cmd_ping.c b/rpp-test-sw/commands/cmd_ping.c new file mode 100644 index 0000000..509e6d4 --- /dev/null +++ b/rpp-test-sw/commands/cmd_ping.c @@ -0,0 +1,199 @@ +/* + * Copyright (C) 2012-2019 Czech Technical University in Prague + * + * Created on: 7.3.2019 + * + * Authors: + * - Jakub Nejedly + * + * This document contains proprietary information belonging to Czech + * Technical University in Prague. Passing on and copying of this + * document, and communication of its contents is not permitted + * without prior written authorization. + * + * File : cmd_ping.c + * + * Abstract: + * + * + */ + +#include "cmd_ping.h" + +#ifndef DOCGEN + + +#include "cmdproc_freertos.h" +#include "rpp/rpp.h" + +#include "lwip/mem.h" +#include "lwip/raw.h" +#include "lwip/icmp.h" +#include "lwip/netif.h" +#include "lwip/sys.h" +#include "lwip/timers.h" +#include "lwip/inet_chksum.h" + +#include "lwip/sockets.h" +#include "lwip/inet.h" + + +#define PING_RCV_TIMEO 1000 +#define PING_DATA_SIZE 32 +#define PING_ID 0xAFAF +#define PING_DELAY 1000 + +static u16_t ping_seq_num; +static u32_t ping_time; + +static void ping_prepare_echo( struct icmp_echo_hdr *iecho, u16_t len){ + + size_t i; + size_t data_len = len - sizeof(struct icmp_echo_hdr); + + ICMPH_TYPE_SET(iecho, ICMP_ECHO); + ICMPH_CODE_SET(iecho, 0); + iecho->chksum = 0; + iecho->id = PING_ID; + iecho->seqno = htons(++ping_seq_num); + + /* fill the additional data buffer with some data */ + for(i = 0; i < data_len; i++) { + ((char*)iecho)[sizeof(struct icmp_echo_hdr) + i] = (char)i; + } + + iecho->chksum = inet_chksum(iecho, len); +} + +static err_t ping_send(int s, ip_addr_t *addr) { + + int err; + struct icmp_echo_hdr *iecho; + struct sockaddr_in to; + size_t ping_size = sizeof(struct icmp_echo_hdr) + PING_DATA_SIZE; + LWIP_ASSERT("ping_size is too big", ping_size <= 0xffff); + + iecho = (struct icmp_echo_hdr *)mem_malloc((mem_size_t)ping_size); + if (!iecho) { + return ERR_MEM; + } + + ping_prepare_echo(iecho, (u16_t)ping_size); + + to.sin_len = sizeof(to); + to.sin_family = AF_INET; + inet_addr_from_ipaddr(&to.sin_addr, addr); + + err = lwip_sendto(s, iecho, ping_size, 0, (struct sockaddr*)&to, sizeof(to)); + + mem_free(iecho); + + return (err ? ERR_OK : ERR_VAL); +} + +static void ping_recv(int s){ + + char buf[256]; + int fromlen, len; + struct sockaddr_in from; + struct ip_hdr *iphdr; + struct icmp_echo_hdr *iecho; + + while((len = lwip_recvfrom(s, buf, sizeof(buf), 0, (struct sockaddr*)&from, (socklen_t*)&fromlen)) > 0 + && (unsigned long)(sys_now() - ping_time) < PING_DELAY-10) { + if (len >= (int)(sizeof(struct ip_hdr)+sizeof(struct icmp_echo_hdr))) { + + ip_addr_t fromaddr; + inet_addr_to_ipaddr(&fromaddr, &from.sin_addr); + + rpp_sci_printf(" time=%lu ms\n", (unsigned long)(sys_now() - ping_time)); + + iphdr = (struct ip_hdr *)buf; + iecho = (struct icmp_echo_hdr *)(buf + (IPH_HL(iphdr) * 4)); + if ((iecho->id == PING_ID) && (iecho->seqno == htons(ping_seq_num))) { + /* do some ping result processing */ + return; + } else { + rpp_sci_printf(" droped\n"); + } + } + } + rpp_sci_printf(" time=%lu ms - timeout \n", (unsigned long)(sys_now() - ping_time)); + + /* do some ping result processing */ + return; +} + + +int cmd_do_eth_ping(cmd_io_t *cmd_io, const struct cmd_des *des, char *param[]){ + + // test ethinit + if (!isPostInitialized()) { + rpp_sci_printf("Eth not initialized run 'ethinit' command first.\n"); + return FAILURE; + } + err_t err = ERR_OK; + + // parse params + ip_addr_t ping_target; + + if ( (err = rpp_eth_stringToIP(&ping_target, (uint8_t *)param[1])) != SUCCESS ) { + rpp_sci_printf("ERR: IP address format\r\n"); + return BAD_OPTION; + } + + // socket creation + int s; + int timeout = PING_RCV_TIMEO; + if ((s = lwip_socket(AF_INET, SOCK_RAW, IP_PROTO_ICMP)) < 0) { + rpp_sci_printf("ERR: lwip socket init\r\n"); + return FAILURE; + } + + /*int ret = */ + lwip_setsockopt(s, SOL_SOCKET, SO_RCVTIMEO, &timeout, sizeof(timeout)); + //rpp_sci_printf("Socket opt result %d \n", ret); + + while (1) { + + if (ping_send(s, &ping_target) == ERR_OK) { + rpp_sci_printf("ping: send to "); + rpp_sci_printf("%s", inet_ntoa(ping_target)); + //rpp_sci_printf("\n"); + + ping_time = sys_now(); + ping_recv(s); + } else { + rpp_sci_printf("ping: send to "); + rpp_sci_printf("%s", inet_ntoa(ping_target)); + rpp_sci_printf(" - error during sending \n"); + } + sys_msleep(PING_DELAY); + } +} + + + +#endif /* DOCGEN */ + +cmd_des_t const cmd_des_ethping = { + 0, 0, + "ethping","Command to send and receive ICMP packets", + "### Command syntax ###\n" + "\n" + " ethping [IP_address] \n" + "\n" + "### Description ###\n" + "basic implementation of outgoing ping" + "\n" + "### Example ###\n" + "\n" + " --> ethping 8.8.8.8\n", + CMD_HANDLER(cmd_do_eth_ping), (void *)&cmd_list_ping +}; + +/** List of commands for adc, defined as external */ +cmd_des_t const *cmd_list_ping[] = { + &cmd_des_ethping, + NULL +}; diff --git a/rpp-test-sw/commands/cmd_ping.h b/rpp-test-sw/commands/cmd_ping.h new file mode 100644 index 0000000..256b796 --- /dev/null +++ b/rpp-test-sw/commands/cmd_ping.h @@ -0,0 +1,18 @@ +/* + * cmd_ping.h + * + * Created on: 7.3.2019 + * Author: Jakub Nejedly + */ + +#ifndef CMD_PING_H_ +#define CMD_PING_H_ + +#define BAD_OPTION -23 + +#include "cmdproc.h" + +extern cmd_des_t const *cmd_list_ping[]; + + +#endif /* CMD_PING_H_ */ -- 2.39.2