Skip to content

Commit ffb252c

Browse files
committed
Drop fragmented IPv4 packets
F/784
1 parent 00ce5fc commit ffb252c

2 files changed

Lines changed: 51 additions & 0 deletions

File tree

src/test/unit/unit.c

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9447,6 +9447,53 @@ START_TEST(test_ip_recv_udp_with_ip_options_delivers_payload)
94479447
}
94489448
END_TEST
94499449

9450+
START_TEST(test_ip_recv_fragmented_udp_dropped)
9451+
{
9452+
struct wolfIP s;
9453+
struct tsocket *ts;
9454+
uint8_t frame[ETH_HEADER_LEN + IP_HEADER_LEN + UDP_HEADER_LEN + 4];
9455+
struct wolfIP_ip_packet *ip = (struct wolfIP_ip_packet *)frame;
9456+
uint8_t *udp_hdr = frame + ETH_HEADER_LEN + IP_HEADER_LEN;
9457+
uint16_t udp_len = UDP_HEADER_LEN + 4;
9458+
uint32_t local_ip = 0x0A000001U;
9459+
uint32_t remote_ip = 0x0A000002U;
9460+
9461+
wolfIP_init(&s);
9462+
mock_link_init(&s);
9463+
wolfIP_ipconfig_set(&s, local_ip, 0xFFFFFF00U, 0);
9464+
9465+
ts = udp_new_socket(&s);
9466+
ck_assert_ptr_nonnull(ts);
9467+
ts->src_port = 1234;
9468+
ts->local_ip = local_ip;
9469+
9470+
memset(frame, 0, sizeof(frame));
9471+
memcpy(ip->eth.dst, s.ll_dev[TEST_PRIMARY_IF].mac, 6);
9472+
memcpy(ip->eth.src, "\x01\x02\x03\x04\x05\x06", 6);
9473+
ip->eth.type = ee16(ETH_TYPE_IP);
9474+
ip->ver_ihl = 0x45;
9475+
ip->ttl = 64;
9476+
ip->proto = WI_IPPROTO_UDP;
9477+
ip->len = ee16(IP_HEADER_LEN + udp_len);
9478+
ip->flags_fo = ee16(0x2000U); /* MF=1, offset=0 */
9479+
ip->src = ee32(remote_ip);
9480+
ip->dst = ee32(local_ip);
9481+
9482+
((uint16_t *)udp_hdr)[0] = ee16(4321);
9483+
((uint16_t *)udp_hdr)[1] = ee16(1234);
9484+
((uint16_t *)udp_hdr)[2] = ee16(udp_len);
9485+
memcpy(udp_hdr + UDP_HEADER_LEN, "frag", 4);
9486+
9487+
fix_udp_checksum_raw(ip, udp_hdr, udp_len);
9488+
fix_ip_checksum(ip);
9489+
9490+
ip_recv(&s, TEST_PRIMARY_IF, ip, (uint32_t)sizeof(frame));
9491+
9492+
ck_assert_ptr_eq(fifo_peek(&ts->sock.udp.rxbuf), NULL);
9493+
ck_assert_uint_eq(ts->events & CB_EVENT_READABLE, 0);
9494+
}
9495+
END_TEST
9496+
94509497
START_TEST(test_ip_recv_forward_arp_queue_and_flush)
94519498
{
94529499
struct wolfIP s;
@@ -20189,6 +20236,7 @@ Suite *wolf_suite(void)
2018920236
tcase_add_test(tc_proto, test_forward_interface_short_circuit_cases);
2019020237
tcase_add_test(tc_proto, test_ip_recv_forward_ttl_exceeded);
2019120238
tcase_add_test(tc_proto, test_ip_recv_udp_with_ip_options_delivers_payload);
20239+
tcase_add_test(tc_proto, test_ip_recv_fragmented_udp_dropped);
2019220240
tcase_add_test(tc_proto, test_ip_recv_forward_arp_queue_and_flush);
2019320241
tcase_add_test(tc_proto, test_arp_flush_pending_ttl_expired);
2019420242
tcase_add_test(tc_proto, test_wolfip_forwarding_basic);

src/wolfip.c

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5889,6 +5889,9 @@ static inline void ip_recv(struct wolfIP *s, unsigned int if_idx,
58895889
/* validate IP header checksum per RFC 1122 */
58905890
if (iphdr_verify_checksum(ip) != 0)
58915891
return;
5892+
/* Fragment reassembly is not implemented; drop all fragments. */
5893+
if ((ee16(ip->flags_fo) & 0x3FFFU) != 0U)
5894+
return;
58925895
#if WOLFIP_ENABLE_LOOPBACK
58935896
if (!wolfIP_is_loopback_if(if_idx)) {
58945897
ip4 dest = ee32(ip->dst);

0 commit comments

Comments
 (0)