diff options
Diffstat (limited to 'src/tests')
-rw-r--r-- | src/tests/tcpip_test.c | 19 |
1 files changed, 18 insertions, 1 deletions
diff --git a/src/tests/tcpip_test.c b/src/tests/tcpip_test.c index 759f886b..fac0ec26 100644 --- a/src/tests/tcpip_test.c +++ b/src/tests/tcpip_test.c @@ -94,6 +94,12 @@ TCPIP_TEST ( one_byte, DATA ( 0xeb ) ); /** Double byte */ TCPIP_TEST ( two_bytes, DATA ( 0xba, 0xbe ) ); +/** Positive zero data */ +TCPIP_TEST ( positive_zero, DATA ( 0x00, 0x00 ) ); + +/** Negative zero data */ +TCPIP_TEST ( negative_zero, DATA ( 0xff, 0xff ) ); + /** Final wrap-around carry (big-endian) */ TCPIP_TEST ( final_carry_big, DATA ( 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01 ) ); @@ -126,9 +132,17 @@ TCPIP_RANDOM_TEST ( partial, 0xcafebabe, 121, 5 ); * * This is a reference implementation taken from RFC1071 (and modified * to fix compilation without warnings under gcc). + * + * The initial value of the one's complement @c sum is changed from + * positive zero (0x0000) to negative zero (0xffff). This ensures + * that the return value will always use the positive representation + * of zero (0x0000). Without this change, the return value would use + * negative zero (0xffff) if the input data is zero length (or all + * zeros) but positive zero (0x0000) for any other data which sums to + * zero. */ static uint16_t rfc_tcpip_chksum ( const void *data, size_t len ) { - unsigned long sum = 0; + unsigned long sum = 0xffff; while ( len > 1 ) { sum += *( ( uint16_t * ) data ); @@ -142,6 +156,7 @@ static uint16_t rfc_tcpip_chksum ( const void *data, size_t len ) { while ( sum >> 16 ) sum = ( ( sum & 0xffff ) + ( sum >> 16 ) ); + assert ( sum != 0x0000 ); return ~sum; } @@ -227,6 +242,8 @@ static void tcpip_test_exec ( void ) { tcpip_ok ( &empty ); tcpip_ok ( &one_byte ); tcpip_ok ( &two_bytes ); + tcpip_ok ( &positive_zero ); + tcpip_ok ( &negative_zero ); tcpip_ok ( &final_carry_big ); tcpip_ok ( &final_carry_little ); tcpip_random_ok ( &random_aligned ); |