summaryrefslogtreecommitdiffstats
path: root/chromium/third_party/usrsctp/usrsctplib/usrsctplib/netinet/sctp_crc32.c
diff options
context:
space:
mode:
Diffstat (limited to 'chromium/third_party/usrsctp/usrsctplib/usrsctplib/netinet/sctp_crc32.c')
-rwxr-xr-xchromium/third_party/usrsctp/usrsctplib/usrsctplib/netinet/sctp_crc32.c124
1 files changed, 63 insertions, 61 deletions
diff --git a/chromium/third_party/usrsctp/usrsctplib/usrsctplib/netinet/sctp_crc32.c b/chromium/third_party/usrsctp/usrsctplib/usrsctplib/netinet/sctp_crc32.c
index 16ce971c7d2..0be0795cf2a 100755
--- a/chromium/third_party/usrsctp/usrsctplib/usrsctplib/netinet/sctp_crc32.c
+++ b/chromium/third_party/usrsctp/usrsctplib/usrsctplib/netinet/sctp_crc32.c
@@ -34,18 +34,30 @@
#ifdef __FreeBSD__
#include <sys/cdefs.h>
-__FBSDID("$FreeBSD: head/sys/netinet/sctp_crc32.c 310590 2016-12-26 11:06:41Z tuexen $");
-#endif
+__FBSDID("$FreeBSD: head/sys/netinet/sctp_crc32.c 327200 2017-12-26 12:35:02Z tuexen $");
+
+#include "opt_sctp.h"
+#ifdef SCTP
#include <netinet/sctp_os.h>
#include <netinet/sctp.h>
#include <netinet/sctp_crc32.h>
#include <netinet/sctp_pcb.h>
+#else
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/mbuf.h>
-
-#if !defined(SCTP_WITH_NO_CSUM)
-#if defined(__FreeBSD__) && __FreeBSD_version >= 800000
+#include <netinet/sctp_crc32.h>
+#endif
#else
+#include <netinet/sctp_os.h>
+#include <netinet/sctp.h>
+#include <netinet/sctp_crc32.h>
+#include <netinet/sctp_pcb.h>
+#endif
+
+#if !defined(__FreeBSD__)
/**
*
* Routine Description:
@@ -713,8 +725,8 @@ calculate_crc32c(uint32_t crc32c,
return (multitable_crc32c(crc32c, buffer, length));
}
}
-#endif /* FreeBSD < 80000 || other OS */
+#endif
#if defined(__Userspace__)
uint32_t
#else
@@ -723,18 +735,16 @@ static uint32_t
sctp_finalize_crc32c(uint32_t crc32c)
{
uint32_t result;
-
#if BYTE_ORDER == BIG_ENDIAN
uint8_t byte0, byte1, byte2, byte3;
-
#endif
+
/* Complement the result */
result = ~crc32c;
#if BYTE_ORDER == BIG_ENDIAN
/*
- * For BIG-ENDIAN.. aka Motorola byte order the result is in
- * little-endian form. So we must manually swap the bytes. Then we
- * can call htonl() which does nothing...
+ * For BIG-ENDIAN platforms the result is in little-endian form. So we
+ * must swap the bytes to return the result in network byte order.
*/
byte0 = result & 0x000000ff;
byte1 = (result >> 8) & 0x000000ff;
@@ -743,66 +753,58 @@ sctp_finalize_crc32c(uint32_t crc32c)
crc32c = ((byte0 << 24) | (byte1 << 16) | (byte2 << 8) | byte3);
#else
/*
- * For INTEL platforms the result comes out in network order. No
- * htonl is required or the swap above. So we optimize out both the
- * htonl and the manual swap above.
+ * For LITTLE ENDIAN platforms the result is in already in network
+ * byte order.
*/
crc32c = result;
#endif
return (crc32c);
}
+/*
+ * Compute the SCTP checksum in network byte order for a given mbuf chain m
+ * which contains an SCTP packet starting at offset.
+ * Since this function is also called by ipfw, don't assume that
+ * it is compiled on a kernel with SCTP support.
+ */
uint32_t
sctp_calculate_cksum(struct mbuf *m, uint32_t offset)
{
- /*
- * given a mbuf chain with a packetheader offset by 'offset'
- * pointing at a sctphdr (with csum set to 0) go through the chain
- * of SCTP_BUF_NEXT()'s and calculate the SCTP checksum. This also
- * has a side bonus as it will calculate the total length of the
- * mbuf chain. Note: if offset is greater than the total mbuf
- * length, checksum=1, pktlen=0 is returned (ie. no real error code)
- */
uint32_t base = 0xffffffff;
- struct mbuf *at;
-
- at = m;
- /* find the correct mbuf and offset into mbuf */
- while ((at != NULL) && (offset > (uint32_t) SCTP_BUF_LEN(at))) {
- offset -= SCTP_BUF_LEN(at); /* update remaining offset
- * left */
- at = SCTP_BUF_NEXT(at);
- }
- while (at != NULL) {
- if ((SCTP_BUF_LEN(at) - offset) > 0) {
- base = calculate_crc32c(base,
- (unsigned char *)(SCTP_BUF_AT(at, offset)),
- (unsigned int)(SCTP_BUF_LEN(at) - offset));
- }
- if (offset) {
- /* we only offset once into the first mbuf */
- if (offset < (uint32_t) SCTP_BUF_LEN(at))
- offset = 0;
- else
- offset -= SCTP_BUF_LEN(at);
+
+ while (offset > 0) {
+ KASSERT(m != NULL, ("sctp_calculate_cksum, offset > length of mbuf chain"));
+ if (offset < (uint32_t)m->m_len) {
+ break;
}
- at = SCTP_BUF_NEXT(at);
+ offset -= m->m_len;
+ m = m->m_next;
+ }
+ if (offset > 0) {
+ base = calculate_crc32c(base,
+ (unsigned char *)(m->m_data + offset),
+ (unsigned int)(m->m_len - offset));
+ m = m->m_next;
+ }
+ while (m != NULL) {
+ base = calculate_crc32c(base,
+ (unsigned char *)m->m_data,
+ (unsigned int)m->m_len);
+ m = m->m_next;
}
base = sctp_finalize_crc32c(base);
return (base);
}
-#endif /* !defined(SCTP_WITH_NO_CSUM) */
-
#if defined(__FreeBSD__)
+#ifdef SCTP
+/*
+ * Compute and insert the SCTP checksum in network byte order for a given
+ * mbuf chain m which contains an SCTP packet starting at offset.
+ */
void
sctp_delayed_cksum(struct mbuf *m, uint32_t offset)
{
-#if defined(SCTP_WITH_NO_CSUM)
-#ifdef INVARIANTS
- panic("sctp_delayed_cksum() called when using no SCTP CRC.");
-#endif
-#else
uint32_t checksum;
checksum = sctp_calculate_cksum(m, offset);
@@ -810,18 +812,18 @@ sctp_delayed_cksum(struct mbuf *m, uint32_t offset)
SCTP_STAT_INCR(sctps_sendswcrc);
offset += offsetof(struct sctphdr, checksum);
- if (offset + sizeof(uint32_t) > (uint32_t) (m->m_len)) {
- SCTP_PRINTF("sctp_delayed_cksum(): m->len: %d, off: %d.\n",
- (uint32_t) m->m_len, offset);
- /*
- * XXX this shouldn't happen, but if it does, the correct
- * behavior may be to insert the checksum in the appropriate
- * next mbuf in the chain.
- */
+ if (offset + sizeof(uint32_t) > (uint32_t)(m->m_len)) {
+#ifdef INVARIANTS
+ panic("sctp_delayed_cksum(): m->m_len: %d, offset: %u.",
+ m->m_len, offset);
+#else
+ SCTP_PRINTF("sctp_delayed_cksum(): m->m_len: %d, offset: %u.\n",
+ m->m_len, offset);
+#endif
return;
}
- *(uint32_t *) (m->m_data + offset) = checksum;
-#endif
+ *(uint32_t *)(m->m_data + offset) = checksum;
}
#endif
+#endif