chunk: Add function to calculate Internet Checksums according to RFC 1071
This commit is contained in:
@@ -783,6 +783,51 @@ START_TEST(test_chunk_hash_static)
|
|||||||
}
|
}
|
||||||
END_TEST
|
END_TEST
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
* test for chunk_internet_checksum[_inc]()
|
||||||
|
*/
|
||||||
|
|
||||||
|
START_TEST(test_chunk_internet_checksum)
|
||||||
|
{
|
||||||
|
chunk_t chunk;
|
||||||
|
u_int16_t sum;
|
||||||
|
|
||||||
|
chunk = chunk_from_chars(0x45,0x00,0x00,0x30,0x44,0x22,0x40,0x00,0x80,0x06,
|
||||||
|
0x00,0x00,0x8c,0x7c,0x19,0xac,0xae,0x24,0x1e,0x2b);
|
||||||
|
|
||||||
|
sum = chunk_internet_checksum(chunk);
|
||||||
|
ck_assert_int_eq(0x442e, ntohs(sum));
|
||||||
|
|
||||||
|
sum = chunk_internet_checksum(chunk_create(chunk.ptr, 10));
|
||||||
|
sum = chunk_internet_checksum_inc(chunk_create(chunk.ptr+10, 10), sum);
|
||||||
|
ck_assert_int_eq(0x442e, ntohs(sum));
|
||||||
|
|
||||||
|
/* need to compensate for even/odd alignment */
|
||||||
|
sum = chunk_internet_checksum(chunk_create(chunk.ptr, 9));
|
||||||
|
sum = ntohs(sum);
|
||||||
|
sum = chunk_internet_checksum_inc(chunk_create(chunk.ptr+9, 11), sum);
|
||||||
|
sum = ntohs(sum);
|
||||||
|
ck_assert_int_eq(0x442e, ntohs(sum));
|
||||||
|
|
||||||
|
chunk = chunk_from_chars(0x45,0x00,0x00,0x30,0x44,0x22,0x40,0x00,0x80,0x06,
|
||||||
|
0x00,0x00,0x8c,0x7c,0x19,0xac,0xae,0x24,0x1e);
|
||||||
|
|
||||||
|
sum = chunk_internet_checksum(chunk);
|
||||||
|
ck_assert_int_eq(0x4459, ntohs(sum));
|
||||||
|
|
||||||
|
sum = chunk_internet_checksum(chunk_create(chunk.ptr, 10));
|
||||||
|
sum = chunk_internet_checksum_inc(chunk_create(chunk.ptr+10, 9), sum);
|
||||||
|
ck_assert_int_eq(0x4459, ntohs(sum));
|
||||||
|
|
||||||
|
/* need to compensate for even/odd alignment */
|
||||||
|
sum = chunk_internet_checksum(chunk_create(chunk.ptr, 9));
|
||||||
|
sum = ntohs(sum);
|
||||||
|
sum = chunk_internet_checksum_inc(chunk_create(chunk.ptr+9, 10), sum);
|
||||||
|
sum = ntohs(sum);
|
||||||
|
ck_assert_int_eq(0x4459, ntohs(sum));
|
||||||
|
}
|
||||||
|
END_TEST
|
||||||
|
|
||||||
/*******************************************************************************
|
/*******************************************************************************
|
||||||
* test for chunk_map and friends
|
* test for chunk_map and friends
|
||||||
*/
|
*/
|
||||||
@@ -1018,6 +1063,10 @@ Suite *chunk_suite_create()
|
|||||||
tcase_add_test(tc, test_chunk_hash_static);
|
tcase_add_test(tc, test_chunk_hash_static);
|
||||||
suite_add_tcase(s, tc);
|
suite_add_tcase(s, tc);
|
||||||
|
|
||||||
|
tc = tcase_create("chunk_internet_checksum");
|
||||||
|
tcase_add_test(tc, test_chunk_internet_checksum);
|
||||||
|
suite_add_tcase(s, tc);
|
||||||
|
|
||||||
tc = tcase_create("chunk_map");
|
tc = tcase_create("chunk_map");
|
||||||
tcase_add_test(tc, test_chunk_map);
|
tcase_add_test(tc, test_chunk_map);
|
||||||
suite_add_tcase(s, tc);
|
suite_add_tcase(s, tc);
|
||||||
|
|||||||
@@ -987,6 +987,37 @@ u_int32_t chunk_hash_static(chunk_t chunk)
|
|||||||
return chunk_mac(chunk, static_key);
|
return chunk_mac(chunk, static_key);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Described in header.
|
||||||
|
*/
|
||||||
|
u_int16_t chunk_internet_checksum_inc(chunk_t data, u_int16_t checksum)
|
||||||
|
{
|
||||||
|
u_int32_t sum = ntohs(~checksum);
|
||||||
|
|
||||||
|
while (data.len > 1)
|
||||||
|
{
|
||||||
|
sum += untoh16(data.ptr);
|
||||||
|
data = chunk_skip(data, 2);
|
||||||
|
}
|
||||||
|
if (data.len)
|
||||||
|
{
|
||||||
|
sum += (u_int16_t)*data.ptr << 8;
|
||||||
|
}
|
||||||
|
while (sum >> 16)
|
||||||
|
{
|
||||||
|
sum = (sum & 0xffff) + (sum >> 16);
|
||||||
|
}
|
||||||
|
return htons(~sum);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Described in header.
|
||||||
|
*/
|
||||||
|
u_int16_t chunk_internet_checksum(chunk_t data)
|
||||||
|
{
|
||||||
|
return chunk_internet_checksum_inc(data, 0xffff);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Described in header.
|
* Described in header.
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -411,6 +411,31 @@ u_int32_t chunk_hash_static_inc(chunk_t chunk, u_int32_t hash);
|
|||||||
*/
|
*/
|
||||||
u_int64_t chunk_mac(chunk_t chunk, u_char *key);
|
u_int64_t chunk_mac(chunk_t chunk, u_char *key);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Calculate the Internet Checksum according to RFC 1071 for the given chunk.
|
||||||
|
*
|
||||||
|
* If the result is used with chunk_internet_checksum_inc() and the data length
|
||||||
|
* is not a multiple of 16 bit the checksum bytes have to be swapped to
|
||||||
|
* compensate the even/odd alignment.
|
||||||
|
*
|
||||||
|
* @param chunk data to process
|
||||||
|
* @return checksum (one's complement, network order)
|
||||||
|
*/
|
||||||
|
u_int16_t chunk_internet_checksum(chunk_t data);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Extend the given Internet Checksum (one's complement, in network byte order)
|
||||||
|
* with the given data.
|
||||||
|
*
|
||||||
|
* If data is not a multiple of 16 bits the checksum may have to be swapped to
|
||||||
|
* compensate even/odd alignment (see chunk_internet_checksum()).
|
||||||
|
*
|
||||||
|
* @param chunk data to process
|
||||||
|
* @param checksum previous checksum (one's complement, network order)
|
||||||
|
* @return checksum (one's complement, network order)
|
||||||
|
*/
|
||||||
|
u_int16_t chunk_internet_checksum_inc(chunk_t data, u_int16_t checksum);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* printf hook function for chunk_t.
|
* printf hook function for chunk_t.
|
||||||
*
|
*
|
||||||
|
|||||||
Reference in New Issue
Block a user