Skip to content

Commit 22eb051

Browse files
rluboskartben
authored andcommitted
tests: net: socket: udp: Add test cases for IPv4-to-IPv6 mapped socket
Add test cases verifying that IPv4-to-IPv6 mapped socket sets the address structure correctly when receiving data from IPv4 peer, and that sending back data to the IPv4-to-IPv6 mapped address works correctly. Signed-off-by: Robert Lubos <[email protected]>
1 parent e27f8cc commit 22eb051

File tree

2 files changed

+132
-0
lines changed

2 files changed

+132
-0
lines changed

tests/net/socket/udp/src/main.c

Lines changed: 129 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,9 +46,11 @@ static const char test_str_all_tx_bufs[] =
4646
;
4747

4848
#define MY_IPV4_ADDR "127.0.0.1"
49+
#define MY_IPV4_MAPPED_ADDR "::ffff:127.0.0.1"
4950
#define MY_IPV6_ADDR "::1"
5051
#define MY_MCAST_IPV4_ADDR "224.0.0.1"
5152
#define MY_MCAST_IPV6_ADDR "ff01::1"
53+
#define ANY_IPV6_ADDR "::"
5254

5355
#define ANY_PORT 0
5456
#define SERVER_PORT 4242
@@ -3586,6 +3588,133 @@ ZTEST_USER(net_socket_udp, test_45_udp_shutdown_recv)
35863588
zassert_equal(rv, 0, "close failed");
35873589
}
35883590

3591+
enum ipv4_mapped_to_ipv6_send_mode {
3592+
IPV4_MAPPED_TO_IPV6_SENDTO,
3593+
IPV4_MAPPED_TO_IPV6_SENDMSG,
3594+
};
3595+
3596+
void test_ipv4_mapped_to_ipv6_send_common(enum ipv4_mapped_to_ipv6_send_mode test_mode)
3597+
{
3598+
int off = 0;
3599+
int ret;
3600+
int sock_s, sock_c;
3601+
socklen_t addrlen;
3602+
struct sockaddr_in addr_c4 = { 0 };
3603+
struct sockaddr_in addr_s4 = { 0 };
3604+
struct sockaddr_in6 addr_s6 = { 0 };
3605+
struct sockaddr_in6 addr_recv = { 0 };
3606+
struct in6_addr mapped_address = { 0 };
3607+
3608+
/* Create IPv4 client socket */
3609+
prepare_sock_udp_v4(MY_IPV4_ADDR, CLIENT_PORT, &sock_c, &addr_c4);
3610+
/* Create IPv6 server socket */
3611+
prepare_sock_udp_v6(ANY_IPV6_ADDR, SERVER_PORT, &sock_s, &addr_s6);
3612+
3613+
/* Prepare server's IPv4 address and expected mapped address */
3614+
addr_s4.sin_family = AF_INET;
3615+
addr_s4.sin_port = htons(SERVER_PORT);
3616+
ret = zsock_inet_pton(AF_INET, MY_IPV4_ADDR, &addr_s4.sin_addr);
3617+
zassert_equal(ret, 1, "inet_pton failed");
3618+
3619+
ret = zsock_inet_pton(AF_INET6, MY_IPV4_MAPPED_ADDR, &mapped_address);
3620+
zassert_equal(ret, 1, "inet_pton failed");
3621+
3622+
/* Bind the client socket to ensure we check the correct address */
3623+
ret = zsock_bind(sock_c, (struct sockaddr *)&addr_c4, sizeof(addr_c4));
3624+
zassert_ok(ret, "bind failed, %d", errno);
3625+
3626+
/* Turn off IPV6_V6ONLY on the server socket, so the socket becomes
3627+
* dual-stack.
3628+
*/
3629+
ret = zsock_setsockopt(sock_s, IPPROTO_IPV6, IPV6_V6ONLY, &off, sizeof(off));
3630+
zassert_ok(ret, "setsockopt failed, %d", errno);
3631+
3632+
/* And bind it to ANY address */
3633+
ret = zsock_bind(sock_s, (struct sockaddr *)&addr_s6, sizeof(addr_s6));
3634+
zassert_ok(ret, "bind failed, %d", errno);
3635+
3636+
/* Send datagram from IPv4 client socket to dual-stack server */
3637+
ret = zsock_sendto(sock_c, TEST_STR_SMALL, sizeof(TEST_STR_SMALL) - 1, 0,
3638+
(struct sockaddr *)&addr_s4, sizeof(addr_s4));
3639+
zexpect_equal(ret, sizeof(TEST_STR_SMALL) - 1,
3640+
"invalid send len (was %d expected %d) (%d)",
3641+
ret, sizeof(TEST_STR_SMALL) - 1, errno);
3642+
3643+
/* Give the packet a chance to go through the net stack */
3644+
k_msleep(10);
3645+
3646+
/* Server should get the datagram, with IPv4-to-IPv6 mapped address */
3647+
addrlen = sizeof(addr_recv);
3648+
clear_buf(rx_buf);
3649+
ret = zsock_recvfrom(sock_s, rx_buf, sizeof(rx_buf), ZSOCK_MSG_DONTWAIT,
3650+
(struct sockaddr *)&addr_recv, &addrlen);
3651+
zassert_true(ret >= 0, "recvfrom fail (%d)", errno);
3652+
zassert_equal(ret, sizeof(TEST_STR_SMALL) - 1, "unexpected received bytes");
3653+
zassert_mem_equal(rx_buf, BUF_AND_SIZE(TEST_STR_SMALL), "wrong data");
3654+
zassert_equal(addrlen, sizeof(struct sockaddr_in6), "unexpected addrlen");
3655+
zassert_equal(addr_recv.sin6_family, AF_INET6,
3656+
"IPv4-to-IPv6 mapped address should be AF_INET6");
3657+
zassert_equal(addr_recv.sin6_port, htons(CLIENT_PORT), "invalid port");
3658+
zassert_mem_equal(&addr_recv.sin6_addr, &mapped_address,
3659+
sizeof(mapped_address), "invalid mapped address");
3660+
3661+
/* Echo data back */
3662+
if (test_mode == IPV4_MAPPED_TO_IPV6_SENDTO) {
3663+
ret = zsock_sendto(sock_s, TEST_STR_SMALL, sizeof(TEST_STR_SMALL) - 1, 0,
3664+
(struct sockaddr *)&addr_recv, addrlen);
3665+
zexpect_equal(ret, sizeof(TEST_STR_SMALL) - 1,
3666+
"invalid send len (was %d expected %d) (%d)",
3667+
ret, sizeof(TEST_STR_SMALL) - 1, errno);
3668+
} else if (test_mode == IPV4_MAPPED_TO_IPV6_SENDMSG) {
3669+
struct msghdr msg = { 0 };
3670+
struct iovec io_vector[1] = { 0 };
3671+
3672+
io_vector[0].iov_base = TEST_STR_SMALL;
3673+
io_vector[0].iov_len = strlen(TEST_STR_SMALL);
3674+
3675+
msg.msg_iov = io_vector;
3676+
msg.msg_iovlen = 1;
3677+
msg.msg_name = &addr_recv;
3678+
msg.msg_namelen = addrlen;
3679+
3680+
ret = zsock_sendmsg(sock_s, &msg, 0);
3681+
zexpect_equal(ret, sizeof(TEST_STR_SMALL) - 1,
3682+
"invalid send len (was %d expected %d) (%d)",
3683+
ret, sizeof(TEST_STR_SMALL) - 1, errno);
3684+
} else {
3685+
zassert_unreachable("invalid test mode");
3686+
}
3687+
3688+
/* Give the packet a chance to go through the net stack */
3689+
k_msleep(10);
3690+
3691+
/* Client should get the echoed datagram */
3692+
clear_buf(rx_buf);
3693+
ret = zsock_recv(sock_c, rx_buf, sizeof(rx_buf), ZSOCK_MSG_DONTWAIT);
3694+
zassert_true(ret >= 0, "recvfrom fail (%d)", errno);
3695+
zassert_equal(ret, sizeof(TEST_STR_SMALL) - 1, "unexpected received bytes");
3696+
zassert_mem_equal(rx_buf, BUF_AND_SIZE(TEST_STR_SMALL), "wrong data");
3697+
3698+
ret = zsock_close(sock_c);
3699+
zassert_ok(ret, "close failed, %d", errno);
3700+
ret = zsock_close(sock_s);
3701+
zassert_ok(ret, "close failed, %d", errno);
3702+
}
3703+
3704+
ZTEST(net_socket_udp, test_46_ipv4_mapped_to_ipv6_sendto)
3705+
{
3706+
Z_TEST_SKIP_IFNDEF(CONFIG_NET_IPV4_MAPPING_TO_IPV6);
3707+
3708+
test_ipv4_mapped_to_ipv6_send_common(IPV4_MAPPED_TO_IPV6_SENDTO);
3709+
}
3710+
3711+
ZTEST(net_socket_udp, test_47_ipv4_mapped_to_ipv6_sendmsg)
3712+
{
3713+
Z_TEST_SKIP_IFNDEF(CONFIG_NET_IPV4_MAPPING_TO_IPV6);
3714+
3715+
test_ipv4_mapped_to_ipv6_send_common(IPV4_MAPPED_TO_IPV6_SENDMSG);
3716+
}
3717+
35893718
static void after(void *arg)
35903719
{
35913720
ARG_UNUSED(arg);

tests/net/socket/udp/testcase.yaml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,3 +45,6 @@ tests:
4545
- CONFIG_TRACING_BACKEND_POSIX=y
4646
- CONFIG_TRACING_PACKET_MAX_SIZE=256
4747
- CONFIG_TRACING_SYNC=y
48+
net.socket.udp.v4_mapping_to_v6_enabled:
49+
extra_configs:
50+
- CONFIG_NET_IPV4_MAPPING_TO_IPV6=y

0 commit comments

Comments
 (0)