@@ -4317,4 +4317,52 @@ START_TEST(test_regression_dns_rcode_error_aborts_query)
43174317END_TEST
43184318
43194319
4320+ /* RFC 768: if the computed UDP checksum is zero, it must be transmitted
4321+ * as 0xFFFF. A zero checksum means "no checksum computed" and the
4322+ * receiver would skip verification. The current code stores the raw
4323+ * transport_checksum result without zero-substitution. */
4324+ START_TEST (test_regression_udp_checksum_zero_substituted_with_ffff )
4325+ {
4326+ struct wolfIP s ;
4327+ struct tsocket * ts ;
4328+ struct wolfIP_udp_datagram udp ;
4329+
4330+ /* Craft a UDP datagram whose pseudo-header + data sums to 0xFFFF
4331+ * in one's complement, causing transport_checksum to return 0.
4332+ *
4333+ * Pseudo-header: src=0, dst=0, proto=0x11, len=8
4334+ * sum = 0x0011 + 0x0008 = 0x0019
4335+ * UDP header: src_port=0xFFDE, dst_port=0, udp_len=8, csum=0
4336+ * sum += 0xFFDE + 0 + 0x0008 = 0xFFE6
4337+ * Total = 0x0019 + 0xFFE6 = 0xFFFF -> ~0xFFFF = 0 */
4338+
4339+ wolfIP_init (& s );
4340+ mock_link_init (& s );
4341+ wolfIP_ipconfig_set (& s , 0 , 0 , 0 );
4342+
4343+ /* Set up a UDP socket so ip_output_add_header can be called */
4344+ ts = & s .udpsockets [0 ];
4345+ memset (ts , 0 , sizeof (* ts ));
4346+ ts -> proto = WI_IPPROTO_UDP ;
4347+ ts -> S = & s ;
4348+ ts -> local_ip = 0 ;
4349+ ts -> remote_ip = 0 ;
4350+ ts -> if_idx = TEST_PRIMARY_IF ;
4351+
4352+ memset (& udp , 0 , sizeof (udp ));
4353+ udp .src_port = ee16 (0xFFDE );
4354+ udp .dst_port = 0 ;
4355+ udp .len = ee16 (8 );
4356+ udp .csum = 0 ;
4357+
4358+ ip_output_add_header (ts , (struct wolfIP_ip_packet * )& udp ,
4359+ WI_IPPROTO_UDP , IP_HEADER_LEN + 8 );
4360+
4361+ /* The stored checksum must be 0xFFFF, not 0. */
4362+ ck_assert_uint_ne (udp .csum , 0 );
4363+ ck_assert_uint_eq (ee16 (udp .csum ), 0xFFFF );
4364+ }
4365+ END_TEST
4366+
4367+
43204368/* ----------------------------------------------------------------------- */
0 commit comments