summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSage Weil <sage@inktank.com>2013-09-27 21:03:06 -0700
committerSage Weil <sage@inktank.com>2013-10-16 09:28:14 -0700
commitc545fc2f4c78026278e626ce87e3232311367959 (patch)
tree254b523057572f8e63992780d61aa3445c8d6b2d
parenta3e9344103525dbbb7dc8cd70a4b8c1df134685d (diff)
downloadceph-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.c57
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] = {