+++ /dev/null
-/* oneC_sum() - One complement`s checksum Author: Kees J. Bot */
-/* 9 May 1995 */
-/* See RFC 1071, "Computing the Internet checksum" */
-/* See also the C version of this code. */
-#include <machine/asm.h>
-
-ENTRY(oneC_sum)
- push %ebp
- movl %esp, %ebp
- push %esi
- push %edi
- movzwl 8(%ebp), %eax /* Checksum of previous block */
- movl 12(%ebp), %esi /* Data to compute checksum over */
- movl 16(%ebp), %edi /* Number of bytes */
-
- xorl %edx, %edx
- xorb %cl, %cl
-align:
- testl $3, %esi /* Is the data aligned? */
- je aligned
- testl %edi, %edi
- je 0f
- movb (%esi), %dl /* Rotate the first unaligned bytes */
- decl %edi /* into the edx register */
-0:
- incl %esi
- rorl $8, %edx
- rorl $8, %eax /* Rotate the checksum likewise */
- addb $8, %cl /* Number of bits rotated */
- jmp align
-aligned:
- addl %edx, %eax /* Summate the unaligned bytes */
- adcl $0, %eax /* Add carry back in for one`s complement */
-
- jmp add6test
-_ALIGN_TEXT
-add6:
- addl (%esi), %eax /* Six times unrolled loop, see below */
- adcl 4(%esi), %eax
- adcl 8(%esi), %eax
- adcl 12(%esi), %eax
- adcl 16(%esi), %eax
- adcl 20(%esi), %eax
- adcl $0, %eax
- addl $24, %esi
-add6test:
- subl $24, %edi
- jae add6
- addl $24, %edi
-
- jmp add1test
-_ALIGN_TEXT
-add1:
- addl (%esi), %eax /* while ((edi -= 4) >= 0) */
- adcl $0, %eax /* eax += *esi++; */
- addl $4, %esi /* edi += 4; */
-add1test:
- subl $4, %edi
- jae add1
- addl $4, %edi
-
- je done /* Are there extra bytes? */
- movl (%esi), %edx /* Load extra bytes in a full dword */
- andl mask-4(,%edi,4), %edx /* Mask off excess */
- addl %edx, %eax /* Add in the last bits */
- adcl $0, %eax
-done:
- roll %cl, %eax /* Undo the rotation at the beginning */
- movl %eax, %edx
- shrl $16, %eax
- addw %dx, %ax /* Add the two words in eax to form */
- adcw $0, %ax /* a 16 bit sum */
- pop %edi
- pop %esi
- pop %ebp
- ret
-
-#ifdef __ACK__
-.rom
-#else
-.data
-#endif
-.balign 4
-mask:
-.long 0x000000FF, 0x0000FFFF, 0x00FFFFFF
-
-/* */
-/* $PchId: oneC_sum.ack.s,v 1.2 1996/03/12 19:33:51 philip Exp $ */
--- /dev/null
+/* oneC_sum() - One complement's checksum Author: Kees J. Bot
+ * 8 May 1995
+ * See RFC 1071, "Computing the Internet checksum"
+ */
+
+#include <sys/types.h>
+#include <net/gen/oneCsum.h>
+
+u16_t oneC_sum(u16_t prev, void *data, size_t size)
+{
+ u8_t *dptr;
+ size_t n;
+ u16_t word;
+ u32_t sum;
+ int swap= 0;
+
+ sum= prev;
+ dptr= data;
+ n= size;
+
+ swap= ((size_t) dptr & 1);
+ if (swap) {
+ sum= ((sum & 0xFF) << 8) | ((sum & 0xFF00) >> 8);
+ if (n > 0) {
+ ((u8_t *) &word)[0]= 0;
+ ((u8_t *) &word)[1]= dptr[0];
+ sum+= (u32_t) word;
+ dptr+= 1;
+ n-= 1;
+ }
+ }
+
+ while (n >= 8) {
+ sum+= (u32_t) ((u16_t *) dptr)[0]
+ + (u32_t) ((u16_t *) dptr)[1]
+ + (u32_t) ((u16_t *) dptr)[2]
+ + (u32_t) ((u16_t *) dptr)[3];
+ dptr+= 8;
+ n-= 8;
+ }
+
+ while (n >= 2) {
+ sum+= (u32_t) ((u16_t *) dptr)[0];
+ dptr+= 2;
+ n-= 2;
+ }
+
+ if (n > 0) {
+ ((u8_t *) &word)[0]= dptr[0];
+ ((u8_t *) &word)[1]= 0;
+ sum+= (u32_t) word;
+ }
+
+ sum= (sum & 0xFFFF) + (sum >> 16);
+ if (sum > 0xFFFF) sum++;
+
+ if (swap) {
+ sum= ((sum & 0xFF) << 8) | ((sum & 0xFF00) >> 8);
+ }
+ return sum;
+}