Skip to content
Merged
Show file tree
Hide file tree
Changes from all 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
7 changes: 7 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -352,6 +352,13 @@ endif

unit-esp: build/test/unit-esp

unit-noeth: build/test/unit-noeth.o

build/test/unit-noeth.o: src/test/unit/unit_noeth.c
@mkdir -p build/test/
@echo "[CC] unit_noeth.c"
@$(CC) $(CFLAGS) -c src/test/unit/unit_noeth.c -o build/test/unit-noeth.o

build/test/unit-esp: src/test/unit/unit_esp.c
@mkdir -p build/test/
@echo "[CC] unit_esp.c"
Expand Down
93 changes: 93 additions & 0 deletions src/test/unit/unit.c
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,8 @@
*/
#include "check.h"
#include "../../../config.h"
#undef DEBUG_UDP
#define DEBUG_UDP 1
#undef CONFIG_IPFILTER
#define CONFIG_IPFILTER 1
#undef WOLFIP_MAX_INTERFACES
Expand Down Expand Up @@ -4642,6 +4644,7 @@ START_TEST(test_sock_getpeername_errors)
ck_assert_int_gt(tcp_sd, 0);
ck_assert_int_eq(wolfIP_sock_getpeername(&s, tcp_sd, NULL, &len), -1);
ck_assert_int_eq(wolfIP_sock_getpeername(&s, tcp_sd, (struct wolfIP_sockaddr *)&sin, &len), -1);
ck_assert_int_eq(wolfIP_sock_getpeername(&s, tcp_sd, (struct wolfIP_sockaddr *)&sin, NULL), -1);
}
END_TEST

Expand Down Expand Up @@ -5353,6 +5356,55 @@ START_TEST(test_sock_recvfrom_icmp_paths)
}
END_TEST

#ifdef DEBUG_UDP
START_TEST(test_wolfip_print_udp_short_len_no_oob)
{
struct wolfIP_udp_datagram udp;

memset(&udp, 0, sizeof(udp));
udp.len = ee16(4); /* Invalid: shorter than UDP header. */
wolfIP_print_udp(&udp);
}
END_TEST
#endif

START_TEST(test_sock_recvfrom_icmp_readable_stays_when_queue_nonempty)
{
struct wolfIP s;
int icmp_sd;
struct tsocket *ts;
struct {
struct wolfIP_icmp_packet icmp;
uint8_t payload[2];
} icmp_frame;
uint8_t rxbuf[ICMP_HEADER_LEN + 2];
int ret;

wolfIP_init(&s);
mock_link_init(&s);

icmp_sd = wolfIP_sock_socket(&s, AF_INET, IPSTACK_SOCK_DGRAM, WI_IPPROTO_ICMP);
ck_assert_int_gt(icmp_sd, 0);
ts = &s.icmpsockets[SOCKET_UNMARK(icmp_sd)];
fifo_init(&ts->sock.udp.rxbuf, ts->rxmem, RXBUF_SIZE);

memset(&icmp_frame, 0, sizeof(icmp_frame));
icmp_frame.icmp.ip.len = ee16(IP_HEADER_LEN + ICMP_HEADER_LEN + sizeof(icmp_frame.payload));
icmp_frame.icmp.type = ICMP_ECHO_REPLY;
icmp_frame.icmp.code = 0;
icmp_frame.payload[0] = 0xAA;
icmp_frame.payload[1] = 0xBB;
ck_assert_int_eq(fifo_push(&ts->sock.udp.rxbuf, &icmp_frame, sizeof(icmp_frame)), 0);
ck_assert_int_eq(fifo_push(&ts->sock.udp.rxbuf, &icmp_frame, sizeof(icmp_frame)), 0);

ts->events |= CB_EVENT_READABLE;
ret = wolfIP_sock_recvfrom(&s, icmp_sd, rxbuf, sizeof(rxbuf), 0, NULL, NULL);
ck_assert_int_eq(ret, ICMP_HEADER_LEN + 2);
ck_assert_ptr_nonnull(fifo_peek(&ts->sock.udp.rxbuf));
ck_assert_uint_ne(ts->events & CB_EVENT_READABLE, 0U);
}
END_TEST

START_TEST(test_sock_recvfrom_udp_short_addrlen)
{
struct wolfIP s;
Expand Down Expand Up @@ -5766,6 +5818,42 @@ START_TEST(test_dns_send_query_errors)
ck_assert_int_eq(dns_send_query(&s, "example.com", &id, DNS_A), -16);
}
END_TEST
START_TEST(test_dns_send_query_invalid_name)
{
struct wolfIP s;
uint16_t id = 0;
char name[260];
size_t pos = 0;

wolfIP_init(&s);
mock_link_init(&s);
s.dns_server = 0x08080808U;
s.dns_id = 0;

memset(name, 'a', 64);
name[64] = '.';
memcpy(name + 65, "com", 3);
name[68] = 0;
ck_assert_int_eq(dns_send_query(&s, name, &id, DNS_A), -22);

s.dns_id = 0;
memset(name, 'a', sizeof(name));
pos = 0;
memset(name + pos, 'a', 63);
pos += 63;
name[pos++] = '.';
memset(name + pos, 'b', 63);
pos += 63;
name[pos++] = '.';
memset(name + pos, 'c', 63);
pos += 63;
name[pos++] = '.';
memset(name + pos, 'd', 63);
pos += 63;
name[pos] = 0;
ck_assert_int_eq(dns_send_query(&s, name, &id, DNS_A), -22);
}
END_TEST
START_TEST(test_fifo_push_and_pop) {
struct fifo f;
struct pkt_desc *desc, *desc2;
Expand Down Expand Up @@ -17348,6 +17436,10 @@ Suite *wolf_suite(void)
tcase_add_test(tc_utils, test_sock_recvfrom_invalid_socket_ids);
tcase_add_test(tc_utils, test_sock_recvfrom_non_socket);
tcase_add_test(tc_utils, test_sock_recvfrom_icmp_success);
#ifdef DEBUG_UDP
tcase_add_test(tc_utils, test_wolfip_print_udp_short_len_no_oob);
#endif
tcase_add_test(tc_utils, test_sock_recvfrom_icmp_readable_stays_when_queue_nonempty);
tcase_add_test(tc_utils, test_sock_opts_unknown_level);
tcase_add_test(tc_utils, test_sock_opts_sol_ip_unknown_optname);
tcase_add_test(tc_utils, test_sock_setsockopt_recvttl);
Expand Down Expand Up @@ -17472,6 +17564,7 @@ Suite *wolf_suite(void)
tcase_add_test(tc_utils, test_dns_skip_and_copy_name);
tcase_add_test(tc_utils, test_sock_opts_and_names);
tcase_add_test(tc_utils, test_dns_send_query_errors);
tcase_add_test(tc_utils, test_dns_send_query_invalid_name);
tcase_add_test(tc_utils, test_dns_wrapper_apis);
tcase_add_test(tc_utils, test_wolfip_static_instance_apis);
tcase_add_test(tc_utils, test_tcp_rto_cb_resets_flags_and_arms_timer);
Expand Down
10 changes: 10 additions & 0 deletions src/test/unit/unit_noeth.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
#include "../../../config.h"
#ifdef ETHERNET
#undef ETHERNET
#endif
#include "../../wolfip.c"

int main(void)
{
return 0;
}
27 changes: 19 additions & 8 deletions src/wolfip.c
Original file line number Diff line number Diff line change
Expand Up @@ -3156,7 +3156,7 @@ static void tcp_input(struct wolfIP *S, unsigned int if_idx,
t->if_idx = (uint8_t)if_idx;
/* TCP segment sanity checks */
iplen = ee16(tcp->ip.len);
if (iplen > frame_len - sizeof(struct wolfIP_eth_frame)) {
if (iplen > frame_len - ETH_HEADER_LEN) {
return; /* discard */
}

Expand Down Expand Up @@ -4178,7 +4178,8 @@ int wolfIP_sock_recvfrom(struct wolfIP *s, int sockfd, void *buf, size_t len, in
}
memcpy(buf, &icmp->type, seg_len);
fifo_pop(&ts->sock.udp.rxbuf);
ts->events &= ~CB_EVENT_READABLE;
if (fifo_peek(&ts->sock.udp.rxbuf) == NULL)
ts->events &= ~CB_EVENT_READABLE;
return (int)seg_len;
} else
return -WOLFIP_EINVAL;
Expand Down Expand Up @@ -4553,7 +4554,7 @@ int wolfIP_sock_getpeername(struct wolfIP *s, int sockfd, struct wolfIP_sockaddr
return -WOLFIP_EINVAL;

ts = &s->tcpsockets[SOCKET_UNMARK(sockfd)];
if (!sin || *addrlen < sizeof(struct wolfIP_sockaddr_in))
if (!sin || !addrlen || *addrlen < sizeof(struct wolfIP_sockaddr_in))
return -1;
sin->sin_family = AF_INET;
sin->sin_port = ee16(ts->dst_port);
Expand Down Expand Up @@ -4597,13 +4598,17 @@ static void icmp_input(struct wolfIP *s, unsigned int if_idx, struct wolfIP_ip_p
ip->id = ipcounter_next(s);
ip->csum = 0;
iphdr_set_checksum(ip);
#ifdef ETHERNET
eth_output_add_header(s, if_idx, ip->eth.src, &ip->eth, ETH_TYPE_IP);
#endif
if (wolfIP_filter_notify_icmp(WOLFIP_FILT_SENDING, s, if_idx, icmp, len) != 0)
return;
if (wolfIP_filter_notify_ip(WOLFIP_FILT_SENDING, s, if_idx, ip, len) != 0)
return;
#ifdef ETHERNET
if (wolfIP_filter_notify_eth(WOLFIP_FILT_SENDING, s, if_idx, &ip->eth, len) != 0)
return;
#endif
if (ll && ll->send)
ll->send(ll, ip, len);
}
Expand Down Expand Up @@ -5472,6 +5477,8 @@ void wolfIP_recv_ex(struct wolfIP *s, unsigned int if_idx, void *buf, uint32_t l
#define DNS_QUERY_TYPE_NONE 0
#define DNS_QUERY_TYPE_A 1
#define DNS_QUERY_TYPE_PTR 2
#define MAX_DNS_NAME_LEN 255
#define MAX_DNS_LABEL_LEN 63

struct PACKED dns_header {
uint16_t id;
Expand Down Expand Up @@ -5691,8 +5698,9 @@ static int dns_send_query(struct wolfIP *s, const char *dname, uint16_t *id,
char *q_name, *tok_start, *tok_end;
struct wolfIP_sockaddr_in dns_srv;
uint32_t tok_len = 0;
uint32_t label_len = 0;
if (!dname || !id) return -22;
if (strlen(dname) > 256) return -22; /* Invalid arguments */
if (strlen(dname) > MAX_DNS_NAME_LEN) return -22; /* Invalid arguments */
if (s->dns_server == 0) return -101; /* Network unreachable: No DNS server configured */
if (s->dns_id != 0) return -16; /* DNS query already in progress */
if (s->dns_udp_sd <= 0) {
Expand All @@ -5718,11 +5726,14 @@ static int dns_send_query(struct wolfIP *s, const char *dname, uint16_t *id,
while ((*tok_end != '.') && (*tok_end != 0)) {
tok_end++;
}
*q_name = tok_end - tok_start;
label_len = (uint32_t)(tok_end - tok_start);
if (label_len > MAX_DNS_LABEL_LEN) return -22;
if (tok_len + label_len + 1 > MAX_DNS_NAME_LEN) return -22;
*q_name = (char)label_len;
q_name++;
memcpy(q_name, tok_start, tok_end - tok_start);
q_name += tok_end - tok_start;
tok_len += (tok_end - tok_start) + 1;
memcpy(q_name, tok_start, label_len);
q_name += label_len;
tok_len += label_len + 1;
if (*tok_end == 0)
break;
tok_start = tok_end + 1;
Expand Down
5 changes: 4 additions & 1 deletion src/wolfip_debug.c
Original file line number Diff line number Diff line change
Expand Up @@ -89,8 +89,11 @@ static void wolfIP_print_udp(struct wolfIP_udp_datagram * udp)
{
/* show first 16 printable chars of payload */
uint16_t max_len = 16;
size_t print_len = (len - 8) < max_len ? (len - 8): max_len;
size_t i = 0;
size_t print_len = 0;
if (len <= UDP_HEADER_LEN)
return;
print_len = (len - 8) < max_len ? (len - 8): max_len;
memset(payload_str, '\0', sizeof(payload_str));
memcpy(payload_str, udp->data, print_len);
for (i = 0; i < print_len; i++) {
Expand Down