diff options
author | Sage Weil <sage@inktank.com> | 2013-09-27 21:03:06 -0700 |
---|---|---|
committer | Sage Weil <sage@inktank.com> | 2013-10-16 09:28:14 -0700 |
commit | c545fc2f4c78026278e626ce87e3232311367959 (patch) | |
tree | 254b523057572f8e63992780d61aa3445c8d6b2d | |
parent | a3e9344103525dbbb7dc8cd70a4b8c1df134685d (diff) | |
download | ceph-c545fc2f4c78026278e626ce87e3232311367959.tar.gz |
common/sctp_crc32: accept NULL buffer pointer
If we get NULL we behave as if it were a zero-filled buffer.
Signed-off-by: Sage Weil <sage@inktank.com>
-rw-r--r-- | src/common/sctp_crc32.c | 57 |
1 files changed, 56 insertions, 1 deletions
diff --git a/src/common/sctp_crc32.c b/src/common/sctp_crc32.c index 7e2678a2b7c..2b4fceccf23 100644 --- a/src/common/sctp_crc32.c +++ b/src/common/sctp_crc32.c @@ -580,6 +580,58 @@ sctp_crc32c_sb8_64_bit(uint32_t crc, return crc; } +static uint32_t +sctp_crc32c_sb8_64_bit_zero(uint32_t crc, + uint32_t length, + uint32_t offset) +{ + uint32_t li; + uint32_t term1, term2; + uint32_t running_length; + uint32_t end_bytes; + uint32_t init_bytes; + + init_bytes = (4-offset) & 0x3; + + if (init_bytes > length) + init_bytes = length; + + running_length = ((length - init_bytes) / 8) * 8; + end_bytes = length - init_bytes - running_length; + + for (li = 0; li < init_bytes; li++) + crc = sctp_crc_tableil8_o32[crc & 0x000000FF] ^ + (crc >> 8); + for (li = 0; li < running_length / 8; li++) { + term1 = sctp_crc_tableil8_o88[crc & 0x000000FF] ^ + sctp_crc_tableil8_o80[(crc >> 8) & 0x000000FF]; + term2 = crc >> 16; + crc = term1 ^ + sctp_crc_tableil8_o72[term2 & 0x000000FF] ^ + sctp_crc_tableil8_o64[(term2 >> 8) & 0x000000FF]; + +#if BYTE_ORDER == BIG_ENDIAN + crc ^= sctp_crc_tableil8_o56[0]; + crc ^= sctp_crc_tableil8_o48[0]; + crc ^= sctp_crc_tableil8_o40[0]; + crc ^= sctp_crc_tableil8_o32[0]; +#else + term1 = sctp_crc_tableil8_o56[0] ^ + sctp_crc_tableil8_o48[0]; + + term2 = 0; + crc = crc ^ + term1 ^ + sctp_crc_tableil8_o40[term2 & 0x000000FF] ^ + sctp_crc_tableil8_o32[(term2 >> 8) & 0x000000FF]; +#endif + } + for (li = 0; li < end_bytes; li++) + crc = sctp_crc_tableil8_o32[crc] ^ + (crc >> 8); + return crc; +} + /** * @@ -606,7 +658,10 @@ update_crc32(uint32_t crc32c, return (crc32c); } offset = ((uintptr_t) buffer) & 0x3; - return (sctp_crc32c_sb8_64_bit(crc32c, buffer, length, offset)); + if (buffer) + return (sctp_crc32c_sb8_64_bit(crc32c, buffer, length, offset)); + else + return (sctp_crc32c_sb8_64_bit_zero(crc32c, length, offset)); } uint32_t sctp_crc_c[256] = { |