diff --git a/test/fuzz.c b/test/fuzz.c index 69a5be3c..397715f7 100644 --- a/test/fuzz.c +++ b/test/fuzz.c @@ -104,7 +104,7 @@ int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) { memcpy(eth->dst, mif.mac, 6); // Set valid destination MAC // send all handled eth types, then 2 random ones if (i >= (sizeof(eth_types) / sizeof(eth_types[0]) + 2)) i = 0; - if (i < (sizeof(eth_types) / sizeof(eth_types[0]))) eth->type = (eth_types[i++]); + if (i < (sizeof(eth_types) / sizeof(eth_types[0]))) eth->type = mg_htons(eth_types[i++]); // build proper layer-3 datagrams, to be able to exercise layers above if (eth->type == mg_htons(0x800) && size > (sizeof(*eth) + sizeof(struct ip))) { // IPv4 static size_t j; diff --git a/test/mip_test.c b/test/mip_test.c index a7b28499..2a855153 100644 --- a/test/mip_test.c +++ b/test/mip_test.c @@ -1076,6 +1076,72 @@ static void test_udp(bool ipv6) { mg_mgr_free(&mgr); } +static void create_icmp_dat(struct eth *e, struct ipp *ipp, uint8_t type, + uint8_t code, size_t payload_len) { + struct icmp icmp; + struct ip *ip = ipp->ip4; + memset(&icmp, 0, sizeof(struct icmp)); + icmp.type = type; + icmp.code = code; + memcpy(s_driver_data.buf, e, sizeof(*e)); + ip->len = mg_htons((uint16_t) (sizeof(*ip) + sizeof(icmp) + payload_len)); + memcpy(s_driver_data.buf + sizeof(*e), ip, sizeof(*ip)); + memcpy(s_driver_data.buf + sizeof(*e) + sizeof(*ip), &icmp, sizeof(icmp)); + s_driver_data.len = sizeof(*e) + sizeof(*ip) + sizeof(icmp) + payload_len; + icmp.csum = ipcsum(s_driver_data.buf + sizeof(*e), sizeof(icmp) + payload_len); + if (s_driver_data.len < 64) s_driver_data.len = 64; // add padding if needed +} + +static void init_icmp_tests(struct mg_mgr *mgr, struct eth *e, struct ipp *ipp, + struct mg_tcpip_driver *driver, + struct mg_tcpip_if *mif) { + init_tests(mgr, e, ipp, driver, mif, 1); // 1 -> ICMP +} + +static void test_icmp_basics(void) { + struct mg_mgr mgr; + struct eth e; + struct ip ip; + struct ipp ipp; + struct icmp *icmp = (struct icmp *) (s_driver_data.buf + sizeof(e) + sizeof(ip)); + struct ip *i = (struct ip *) (s_driver_data.buf + sizeof(e)); + struct mg_tcpip_driver driver; + struct mg_tcpip_if mif; + + ipp.ip4 = &ip; + ipp.ip6 = NULL; + init_icmp_tests(&mgr, &e, &ipp, &driver, &mif); + + create_icmp_dat(&e, &ipp, 8, 0, 0); + mg_mgr_poll(&mgr, 0); // make sure we clean former stuff in buffer + while (!received_response(&s_driver_data)) mg_mgr_poll(&mgr, 0); + ASSERT(i->src == 1 && i->dst == 2); + ASSERT(i->proto == 1); + ASSERT(i->len == mg_htons(sizeof(*i) + sizeof(*icmp) + 0)); + ASSERT(ipcsum(i, sizeof(*i)) == 0); // Bonus, not tested elsewhere + ASSERT(icmp->type == 0); // Echo Reply + ASSERT(icmp->code == 0); + ASSERT(ipcsum(icmp, sizeof(*icmp) + 0) == 0); + + create_icmp_dat(&e, &ipp, 8, 0, 69); + mg_mgr_poll(&mgr, 0); // make sure we clean former stuff in buffer + while (!received_response(&s_driver_data)) mg_mgr_poll(&mgr, 0); + ASSERT(i->src == 1 && i->dst == 2); + ASSERT(i->proto == 1); + ASSERT(i->len == mg_htons(sizeof(*i) + sizeof(*icmp) + 69)); + ASSERT(icmp->type == 0); // Echo Reply + ASSERT(icmp->code == 0); + ASSERT(ipcsum(icmp, sizeof(*icmp) + 69) == 0); + + s_driver_data.len = 0; + mg_mgr_free(&mgr); +} + +static void test_icmp(void) { + test_icmp_basics(); +} + + #define DASHBOARD(x) \ printf("HEALTH_DASHBOARD\t\"%s\": %s,\n", x, s_error ? "false" : "true"); @@ -1093,6 +1159,10 @@ int main(void) { test_poll(); DASHBOARD("poll"); + s_error = false; + test_icmp(); + DASHBOARD("icmp"); + s_error = false; test_tcp(false); DASHBOARD("tcp");