Skip to content

Commit b1c4c9a

Browse files
author
David Čermák
committed
Merge branch 'fix/lwip_ping_ipv6only_v5.4' into 'release/v5.4'
fix(lwip): Fix IP6 raw socket checksum in IPv6-only configuration (v5.4) See merge request espressif/esp-idf!35083
2 parents c122f72 + 2822cc6 commit b1c4c9a

File tree

6 files changed

+63
-8
lines changed

6 files changed

+63
-8
lines changed

components/lwip/apps/ping/ping_sock.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -133,7 +133,8 @@ static int esp_ping_receive(esp_ping_t *ep)
133133
if (IP_IS_V6_VAL(recv_addr)) { // Currently we process IPv6
134134
struct ip6_hdr *iphdr = (struct ip6_hdr *)buf;
135135
struct icmp6_echo_hdr *iecho6 = (struct icmp6_echo_hdr *)(buf + sizeof(struct ip6_hdr)); // IPv6 head length is 40
136-
if ((iecho6->id == ep->packet_hdr->id) && (iecho6->seqno == ep->packet_hdr->seqno)) {
136+
if ((iecho6->type == ICMP6_TYPE_EREP) // only check the ICMPv6 echo reply types
137+
&& (iecho6->id == ep->packet_hdr->id) && (iecho6->seqno == ep->packet_hdr->seqno)) {
137138
ip_addr_copy(ep->recv_addr, recv_addr);
138139
ep->received++;
139140
ep->recv_len = IP6H_PLEN(iphdr) - sizeof(struct icmp6_echo_hdr); //The data portion of ICMPv6

examples/common_components/protocol_examples_common/stdin_out.c

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -15,8 +15,7 @@
1515

1616
esp_err_t example_configure_stdin_stdout(void)
1717
{
18-
static bool configured = false;
19-
if (configured) {
18+
if (uart_is_driver_installed((uart_port_t)CONFIG_ESP_CONSOLE_UART_NUM)) {
2019
return ESP_OK;
2120
}
2221
// Initialize VFS & UART so we can use std::cout/cin
@@ -29,6 +28,5 @@ esp_err_t example_configure_stdin_stdout(void)
2928
uart_vfs_dev_port_set_rx_line_endings(CONFIG_ESP_CONSOLE_UART_NUM, ESP_LINE_ENDINGS_CR);
3029
/* Move the caret to the beginning of the next line on '\n' */
3130
uart_vfs_dev_port_set_tx_line_endings(CONFIG_ESP_CONSOLE_UART_NUM, ESP_LINE_ENDINGS_CRLF);
32-
configured = true;
3331
return ESP_OK;
3432
}

examples/protocols/icmp_echo/main/echo_example_main.c

Lines changed: 21 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -62,11 +62,16 @@ static void cmd_ping_on_ping_end(esp_ping_handle_t hdl, void *args)
6262
} else {
6363
loss = 0;
6464
}
65+
#ifdef CONFIG_LWIP_IPV4
6566
if (IP_IS_V4(&target_addr)) {
6667
printf("\n--- %s ping statistics ---\n", inet_ntoa(*ip_2_ip4(&target_addr)));
67-
} else {
68+
}
69+
#endif
70+
#ifdef CONFIG_LWIP_IPV6
71+
if (IP_IS_V6(&target_addr)) {
6872
printf("\n--- %s ping statistics ---\n", inet6_ntoa(*ip_2_ip6(&target_addr)));
6973
}
74+
#endif
7075
printf("%" PRIu32 " packets transmitted, %" PRIu32 " received, %" PRIu32 "%% packet loss, time %" PRIu32 "ms\n",
7176
transmitted, received, loss, total_time_ms);
7277
// delete the ping sessions, so that we clean up all resources and can create a new ping session
@@ -81,6 +86,7 @@ static struct {
8186
struct arg_int *count;
8287
struct arg_int *tos;
8388
struct arg_int *ttl;
89+
struct arg_int *interface;
8490
struct arg_str *host;
8591
struct arg_end *end;
8692
} ping_args;
@@ -119,6 +125,10 @@ static int do_ping_cmd(int argc, char **argv)
119125
config.ttl = (uint32_t)(ping_args.ttl->ival[0]);
120126
}
121127

128+
if (ping_args.interface->count > 0) {
129+
config.interface = (uint32_t)(ping_args.interface->ival[0]);
130+
}
131+
122132
// parse IP address
123133
struct sockaddr_in6 sock_addr6;
124134
ip_addr_t target_addr;
@@ -136,13 +146,18 @@ static int do_ping_cmd(int argc, char **argv)
136146
printf("ping: unknown host %s\n", ping_args.host->sval[0]);
137147
return 1;
138148
}
149+
#ifdef CONFIG_LWIP_IPV4
139150
if (res->ai_family == AF_INET) {
140151
struct in_addr addr4 = ((struct sockaddr_in *) (res->ai_addr))->sin_addr;
141152
inet_addr_to_ip4addr(ip_2_ip4(&target_addr), &addr4);
142-
} else {
153+
}
154+
#endif
155+
#ifdef CONFIG_LWIP_IPV6
156+
if (res->ai_family == AF_INET6) {
143157
struct in6_addr addr6 = ((struct sockaddr_in6 *) (res->ai_addr))->sin6_addr;
144158
inet6_addr_to_ip6addr(ip_2_ip6(&target_addr), &addr6);
145159
}
160+
#endif
146161
freeaddrinfo(res);
147162
}
148163
config.target_addr = target_addr;
@@ -169,6 +184,7 @@ static void register_ping(void)
169184
ping_args.count = arg_int0("c", "count", "<n>", "Stop after sending count packets");
170185
ping_args.tos = arg_int0("Q", "tos", "<n>", "Set Type of Service related bits in IP datagrams");
171186
ping_args.ttl = arg_int0("T", "ttl", "<n>", "Set Time to Live related bits in IP datagrams");
187+
ping_args.interface = arg_int0("I", "interface", "<n>", "Set Interface number");
172188
ping_args.host = arg_str1(NULL, NULL, "<host>", "Host address");
173189
ping_args.end = arg_end(1);
174190
const esp_console_cmd_t ping_cmd = {
@@ -232,6 +248,9 @@ void app_main(void)
232248
/* automatic connection per menuconfig */
233249
ESP_ERROR_CHECK(example_connect());
234250
#endif
251+
struct ifreq ifr;
252+
ESP_ERROR_CHECK(esp_netif_get_netif_impl_name(EXAMPLE_INTERFACE, ifr.ifr_name));
253+
printf("Connected on interface: %s (%d)", ifr.ifr_name, esp_netif_get_netif_impl_index(EXAMPLE_INTERFACE));
235254

236255
/* register command `ping` */
237256
register_ping();

examples/protocols/icmp_echo/pytest_icmp_echo.py

Lines changed: 32 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
1-
# SPDX-FileCopyrightText: 2021-2023 Espressif Systems (Shanghai) CO LTD
1+
# SPDX-FileCopyrightText: 2021-2024 Espressif Systems (Shanghai) CO LTD
22
# SPDX-License-Identifier: Apache-2.0
3+
import logging
34
import os
45

56
import pytest
@@ -56,3 +57,33 @@ def test_protocols_icmp_echo(dut: Dut) -> None:
5657
)
5758
def test_protocols_icmp_echo_esp32c2_26mhz(dut: Dut) -> None:
5859
_run_test(dut)
60+
61+
62+
@pytest.mark.esp32
63+
@pytest.mark.wifi_router
64+
@pytest.mark.parametrize('config', ['ipv6_only',], indirect=True)
65+
def test_protocols_icmp_echo_ipv6_only(dut: Dut) -> None:
66+
# Parse IP address of STA
67+
logging.info('Waiting to connect with AP')
68+
if dut.app.sdkconfig.get('EXAMPLE_WIFI_SSID_PWD_FROM_STDIN') is True:
69+
dut.expect('Please input ssid password:')
70+
env_name = 'wifi_router'
71+
ap_ssid = get_env_config_variable(env_name, 'ap_ssid')
72+
ap_password = get_env_config_variable(env_name, 'ap_password')
73+
dut.write(f'{ap_ssid} {ap_password}')
74+
# expect all 8 octets from IPv6 (assumes it's printed in the long form)
75+
ipv6_r = r':'.join((r'[0-9a-fA-F]{4}',) * 8)
76+
ipv6 = dut.expect(ipv6_r, timeout=30)[0].decode()
77+
logging.info(f'Connected AP with IPv6={ipv6}')
78+
interface_nr = dut.expect(r'Connected on interface: [a-z]{2}\d \((\d+)\)', timeout=30)[1].decode()
79+
80+
# ping our own address to simplify things
81+
dut.write('ping -I {} {} -c 5'.format(interface_nr, ipv6))
82+
83+
# expect at least two packets (there could be lost packets)
84+
ip = dut.expect(r'64 bytes from ([0-9a-fA-F:]+) icmp_seq=\d ttl=\d+ time=\d+ ms')[1].decode()
85+
dut.expect(fr'64 bytes from {ip} icmp_seq=[2-5] ttl=\d+ time=')
86+
87+
dut.expect(r'5 packets transmitted, [2-5] received, \d{1,3}% packet loss')
88+
dut.write('')
89+
dut.expect('esp>')
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
CONFIG_IDF_TARGET="esp32"
2+
CONFIG_EXAMPLE_WIFI_SSID_PWD_FROM_STDIN=y
3+
CONFIG_EXAMPLE_CONNECT_IPV4=n
4+
CONFIG_EXAMPLE_CONNECT_IPV6=y
5+
CONFIG_LWIP_IPV4=n
6+
CONFIG_LWIP_IPV6=y

0 commit comments

Comments
 (0)