Skip to content
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
175 changes: 175 additions & 0 deletions src/test/unit/unit.c
Original file line number Diff line number Diff line change
Expand Up @@ -1039,6 +1039,173 @@ START_TEST(test_udp_sendto_and_recvfrom)
}
Comment thread
danielinux marked this conversation as resolved.
END_TEST

START_TEST(test_udp_recvfrom_sets_remote_ip)
{
struct wolfIP s;
int sd;
struct wolfIP_sockaddr_in sin;
uint8_t payload[4] = {0xAA, 0xBB, 0xCC, 0xDD};
uint8_t rxbuf[4] = {0};
struct wolfIP_sockaddr_in from;
socklen_t from_len = sizeof(from);
int ret;
ip4 local_ip = 0x0A000001U;
ip4 remote_ip = 0x0A000002U;
uint16_t local_port = 4001;
uint16_t remote_port = 5001;
struct tsocket *ts;

wolfIP_init(&s);
mock_link_init(&s);
wolfIP_ipconfig_set(&s, local_ip, 0xFFFFFF00U, 0);

sd = wolfIP_sock_socket(&s, AF_INET, IPSTACK_SOCK_DGRAM, WI_IPPROTO_UDP);
ck_assert_int_gt(sd, 0);

memset(&sin, 0, sizeof(sin));
sin.sin_family = AF_INET;
sin.sin_port = ee16(local_port);
sin.sin_addr.s_addr = ee32(local_ip);
ret = wolfIP_sock_bind(&s, sd, (struct wolfIP_sockaddr *)&sin, sizeof(sin));
ck_assert_int_eq(ret, 0);

ts = &s.udpsockets[SOCKET_UNMARK(sd)];
ck_assert_uint_eq(ts->remote_ip, 0);

inject_udp_datagram(&s, TEST_PRIMARY_IF, remote_ip, local_ip, remote_port, local_port,
payload, sizeof(payload));

memset(&from, 0, sizeof(from));
ret = wolfIP_sock_recvfrom(&s, sd, rxbuf, sizeof(rxbuf), 0,
(struct wolfIP_sockaddr *)&from, &from_len);
ck_assert_int_eq(ret, (int)sizeof(payload));
ck_assert_mem_eq(rxbuf, payload, sizeof(payload));
ck_assert_uint_eq(from.sin_addr.s_addr, ee32(remote_ip));
ck_assert_uint_eq(ts->remote_ip, remote_ip);
Comment thread
danielinux marked this conversation as resolved.
}
END_TEST

START_TEST(test_udp_recvfrom_null_src_addr_len)
{
struct wolfIP s;
int sd;
struct wolfIP_sockaddr_in sin;
uint8_t payload[4] = {0x11, 0x22, 0x33, 0x44};
uint8_t rxbuf[4] = {0};
int ret;
ip4 local_ip = 0x0A000001U;
ip4 remote_ip = 0x0A000002U;
uint16_t local_port = 4002;
uint16_t remote_port = 5002;

wolfIP_init(&s);
mock_link_init(&s);
wolfIP_ipconfig_set(&s, local_ip, 0xFFFFFF00U, 0);

sd = wolfIP_sock_socket(&s, AF_INET, IPSTACK_SOCK_DGRAM, WI_IPPROTO_UDP);
ck_assert_int_gt(sd, 0);

memset(&sin, 0, sizeof(sin));
sin.sin_family = AF_INET;
sin.sin_port = ee16(local_port);
sin.sin_addr.s_addr = ee32(local_ip);
ret = wolfIP_sock_bind(&s, sd, (struct wolfIP_sockaddr *)&sin, sizeof(sin));
ck_assert_int_eq(ret, 0);

inject_udp_datagram(&s, TEST_PRIMARY_IF, remote_ip, local_ip, remote_port, local_port,
payload, sizeof(payload));

ret = wolfIP_sock_recvfrom(&s, sd, rxbuf, sizeof(rxbuf), 0, NULL, NULL);
ck_assert_int_eq(ret, (int)sizeof(payload));
ck_assert_mem_eq(rxbuf, payload, sizeof(payload));
}
END_TEST

START_TEST(test_udp_recvfrom_preserves_remote_ip)
{
struct wolfIP s;
int sd;
struct wolfIP_sockaddr_in sin;
uint8_t payload[4] = {0x55, 0x66, 0x77, 0x88};
uint8_t rxbuf[4] = {0};
struct wolfIP_sockaddr_in from;
socklen_t from_len = sizeof(from);
int ret;
ip4 local_ip = 0x0A000001U;
ip4 remote_ip = 0x0A000002U;
ip4 preset_remote_ip = 0x0A000099U;
uint16_t local_port = 4003;
uint16_t remote_port = 5003;
struct tsocket *ts;

wolfIP_init(&s);
mock_link_init(&s);
wolfIP_ipconfig_set(&s, local_ip, 0xFFFFFF00U, 0);

sd = wolfIP_sock_socket(&s, AF_INET, IPSTACK_SOCK_DGRAM, WI_IPPROTO_UDP);
ck_assert_int_gt(sd, 0);

memset(&sin, 0, sizeof(sin));
sin.sin_family = AF_INET;
sin.sin_port = ee16(local_port);
sin.sin_addr.s_addr = ee32(local_ip);
ret = wolfIP_sock_bind(&s, sd, (struct wolfIP_sockaddr *)&sin, sizeof(sin));
ck_assert_int_eq(ret, 0);

ts = &s.udpsockets[SOCKET_UNMARK(sd)];
ts->remote_ip = preset_remote_ip;

inject_udp_datagram(&s, TEST_PRIMARY_IF, remote_ip, local_ip, remote_port, local_port,
payload, sizeof(payload));

memset(&from, 0, sizeof(from));
ret = wolfIP_sock_recvfrom(&s, sd, rxbuf, sizeof(rxbuf), 0,
(struct wolfIP_sockaddr *)&from, &from_len);
ck_assert_int_eq(ret, (int)sizeof(payload));
ck_assert_mem_eq(rxbuf, payload, sizeof(payload));
ck_assert_uint_eq(from.sin_addr.s_addr, ee32(remote_ip));
ck_assert_uint_eq(ts->remote_ip, preset_remote_ip);
}
END_TEST

START_TEST(test_udp_recvfrom_null_addrlen)
{
struct wolfIP s;
int sd;
struct wolfIP_sockaddr_in sin;
uint8_t payload[4] = {0x9A, 0xBC, 0xDE, 0xF0};
uint8_t rxbuf[4] = {0};
struct wolfIP_sockaddr_in from;
int ret;
ip4 local_ip = 0x0A000001U;
ip4 remote_ip = 0x0A000002U;
uint16_t local_port = 4004;
uint16_t remote_port = 5004;

wolfIP_init(&s);
mock_link_init(&s);
wolfIP_ipconfig_set(&s, local_ip, 0xFFFFFF00U, 0);

sd = wolfIP_sock_socket(&s, AF_INET, IPSTACK_SOCK_DGRAM, WI_IPPROTO_UDP);
ck_assert_int_gt(sd, 0);

memset(&sin, 0, sizeof(sin));
sin.sin_family = AF_INET;
sin.sin_port = ee16(local_port);
sin.sin_addr.s_addr = ee32(local_ip);
ret = wolfIP_sock_bind(&s, sd, (struct wolfIP_sockaddr *)&sin, sizeof(sin));
ck_assert_int_eq(ret, 0);

inject_udp_datagram(&s, TEST_PRIMARY_IF, remote_ip, local_ip, remote_port, local_port,
payload, sizeof(payload));

memset(&from, 0, sizeof(from));
ret = wolfIP_sock_recvfrom(&s, sd, rxbuf, sizeof(rxbuf), 0,
(struct wolfIP_sockaddr *)&from, NULL);
ck_assert_int_eq(ret, -1);
}
END_TEST

START_TEST(test_sock_error_paths)
{
struct wolfIP s;
Expand Down Expand Up @@ -12082,6 +12249,14 @@ Suite *wolf_suite(void)
suite_add_tcase(s, tc_proto);
tcase_add_test(tc_proto, test_udp_sendto_and_recvfrom);
suite_add_tcase(s, tc_proto);
tcase_add_test(tc_proto, test_udp_recvfrom_sets_remote_ip);
suite_add_tcase(s, tc_proto);
tcase_add_test(tc_proto, test_udp_recvfrom_null_src_addr_len);
suite_add_tcase(s, tc_proto);
tcase_add_test(tc_proto, test_udp_recvfrom_preserves_remote_ip);
suite_add_tcase(s, tc_proto);
tcase_add_test(tc_proto, test_udp_recvfrom_null_addrlen);
suite_add_tcase(s, tc_proto);
tcase_add_test(tc_proto, test_dns_query_and_callback_a);
suite_add_tcase(s, tc_proto);
tcase_add_test(tc_proto, test_dhcp_parse_offer_and_ack);
Expand Down
6 changes: 5 additions & 1 deletion src/wolfip.c
Original file line number Diff line number Diff line change
Expand Up @@ -2647,17 +2647,21 @@ int wolfIP_sock_recvfrom(struct wolfIP *s, int sockfd, void *buf, size_t len, in
if (SOCKET_UNMARK(sockfd) >= MAX_UDPSOCKETS)
return -WOLFIP_EINVAL;
ts = &s->udpsockets[SOCKET_UNMARK(sockfd)];
if (sin && !addrlen)
return -1;
if (sin && *addrlen < sizeof(struct wolfIP_sockaddr_in))
return -1;
Comment thread
danielinux marked this conversation as resolved.
Outdated
if (addrlen) *addrlen = sizeof(struct wolfIP_sockaddr_in);
if (fifo_len(&ts->sock.udp.rxbuf) == 0)
return -WOLFIP_EAGAIN;
desc = fifo_peek(&ts->sock.udp.rxbuf);
udp = (struct wolfIP_udp_datagram *)(ts->rxmem + desc->pos + sizeof(*desc));
if (ts->remote_ip == 0)
ts->remote_ip = ee32(udp->ip.src);
Comment thread
danielinux marked this conversation as resolved.
Outdated
if (sin) {
sin->sin_family = AF_INET;
sin->sin_port = ee16(udp->src_port);
Comment thread
danielinux marked this conversation as resolved.
Outdated
sin->sin_addr.s_addr = ee32(ts->remote_ip);
sin->sin_addr.s_addr = udp->ip.src;
Comment thread
danielinux marked this conversation as resolved.
Outdated
}
seg_len = ee16(udp->len) - UDP_HEADER_LEN;
if (seg_len > len)
Expand Down