2024-07-22 05:45 AM
I'm utilizing two nucleo f767zi boards with the goal to get them to ping eachother using Ethernet with lwip and no RTOS. Both their Ethernet cables are connected to a switch which is also connected to my PC. With cubeide I've successfully pinged the boards from my PC using the functions ethernetif_input->low_level_input() and ping in the command prompt (windows).
Now i want to ping one board from the other board. The first board is set up as before and prints out the length och the packets received as well as a LED to identify successful transmission.
With the other board i'm trying to utilize the function low_level_output(). It is setup so that when i press the user button the following code is executed.
struct pbuf *my_package_2_send;
const char data_2_send[] = "Hello, World!";
my_package_2_send = pbuf_alloc(PBUF_RAW , strlen(data_2_send), PBUF_POOL);
pbuf_take(my_package_2_send, data_2_send, strlen(data_2_send));
low_level_output(netif ,my_package_2_send);
pbuf_free(my_package_2_send);
When pressing the button i can see the yellow light on the rj-45 connector flash on the receiving board but i can not see any packet received.
I'm fairly sure this has to do with the fact that i've not setup my payload with proper headers and neither have i entered the receivers IP address anywhere right now. However, I'm unable to find information on how to do this properly nor any built in function to do this?
Is there any function to easily create correct headers?
Have i misunderstood the function that i'm currently trying to use?
Anyone else created similar programs before, how did you approach it?
2024-09-16 05:41 AM
Hello @Eld_Eddan ,
The ICMP packet consists of an ICMP header followed by the payload.
The ICMP header includes fields like type, code, checksum, identifier, and sequence number.
if you want to get the full flow of the construction of a packet, take a look at the following Github repo :stm32-hotspot/CKB-STM32-HAL-Ethernet-BareMetal: Ethernet BareMetal configuration and minimal implementation on STM32H5/H7 series (github.com)
you can refer to this esp-idf/components/lwip/apps/ping/ping.c at master · espressif/esp-idf (github.com)
line 160 and onwards showing how to implement ping with LWIP :
/** Prepare a echo ICMP request */
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);
}
/* Ping using the raw ip */
static u8_t
ping_recv(void *arg, struct raw_pcb *pcb, struct pbuf *p, const ip_addr_t *addr)
{
struct icmp_echo_hdr *iecho;
struct timeval now;
LWIP_UNUSED_ARG(arg);
LWIP_UNUSED_ARG(pcb);
LWIP_UNUSED_ARG(addr);
LWIP_ASSERT("p != NULL", p != NULL);
if ((p->tot_len >= (PBUF_IP_HLEN + sizeof(struct icmp_echo_hdr))) &&
pbuf_header(p, -PBUF_IP_HLEN) == 0) {
iecho = (struct icmp_echo_hdr *)p->payload;
if ((iecho->id == PING_ID) && (iecho->seqno == htons(ping_seq_num))) {
LWIP_DEBUGF( PING_DEBUG, ("ping: recv "));
ip_addr_debug_print(PING_DEBUG, addr);
gettimeofday(&now, NULL);
LWIP_DEBUGF( PING_DEBUG, (" %"U32_F" ms\n", PING_TIME_DIFF_MS(now, ping_time)));
/* do some ping result processing */
PING_RESULT(1);
pbuf_free(p);
return 1; /* eat the packet */
}
/* not eaten, restore original packet */
pbuf_header(p, PBUF_IP_HLEN);
}
return 0; /* don't eat the packet */
}
static void
ping_send(struct raw_pcb *raw, ip_addr_t *addr)
{
struct pbuf *p;
struct icmp_echo_hdr *iecho;
size_t ping_size = sizeof(struct icmp_echo_hdr) + PING_DATA_SIZE;
LWIP_DEBUGF( PING_DEBUG, ("ping: send "));
ip_addr_debug_print(PING_DEBUG, addr);
LWIP_DEBUGF( PING_DEBUG, ("\n"));
LWIP_ASSERT("ping_size <= 0xffff", ping_size <= 0xffff);
p = pbuf_alloc(PBUF_IP, (u16_t)ping_size, PBUF_RAM);
if (!p) {
return;
}
if ((p->len == p->tot_len) && (p->next == NULL)) {
iecho = (struct icmp_echo_hdr *)p->payload;
ping_prepare_echo(iecho, (u16_t)ping_size);
raw_sendto(raw, p, addr);
ping_time = system_get_time();
}
pbuf_free(p);
}
Regards
2024-09-26 03:57 AM
Hello @Eld_Eddan ,
did you manage to solve your issue?
Regards