Commit | Line | Data |
---|---|---|
4d0a6cbd | 1 | /* in_cksum.c 1.4 81/10/20 */ |
51041fae BJ |
2 | |
3 | #include <sys/types.h> | |
4 | #include "../bbnnet/net.h" | |
5 | #include "../bbnnet/count.h" | |
6 | ||
7 | /* | |
8 | * Network primitives; this file varies per-cpu, | |
9 | * and the code here is for VAX only. | |
10 | */ | |
51041fae BJ |
11 | |
12 | /* | |
13 | * Checksum routine for TCP/IP headers. This | |
14 | * is very heavily used in the network | |
15 | * code and should be rewritten for each CPU | |
16 | * to be as fast as possible. | |
17 | */ | |
1e92f1b1 | 18 | cksum(m, len) |
51041fae BJ |
19 | register struct mbuf *m; |
20 | register int len; | |
21 | { | |
4d0a6cbd | 22 | register long *l; /* known to be r9 */ |
51041fae | 23 | register int sum = 0; /* known to be r8 */ |
4d0a6cbd | 24 | register u_short *w; /* known to be r7 */ |
51041fae | 25 | register int mlen = 0; |
1e92f1b1 | 26 | COUNT(CKSUM); |
51041fae BJ |
27 | |
28 | for (;;) { | |
29 | w = (u_short *)((int)m + m->m_off); | |
30 | if (mlen == -1) { | |
31 | sum += *(u_char *)w << 8; | |
32 | w = (unsigned short *)((char *)w + 1); | |
33 | mlen = m->m_len - 1; | |
34 | len--; | |
35 | } else | |
36 | mlen = m->m_len; | |
37 | m = m->m_next; | |
38 | if (len < mlen) | |
39 | mlen = len; | |
40 | len -= mlen; | |
4d0a6cbd | 41 | l = (long *)w; |
51041fae | 42 | while ((mlen -= 32) >= 0) { |
4d0a6cbd BJ |
43 | asm("clrl r0"); /* clears carry */ |
44 | #undef ADD | |
45 | #define ADD asm("adwc (r9)+,r8;"); | |
51041fae | 46 | ADD; ADD; ADD; ADD; ADD; ADD; ADD; ADD; |
4d0a6cbd | 47 | asm("adwc $0,r8"); |
51041fae BJ |
48 | } |
49 | mlen += 32; | |
50 | while ((mlen -= 8) >= 0) { | |
4d0a6cbd BJ |
51 | asm("clrl r0"); |
52 | ADD; ADD; | |
53 | asm("adwc $0,r8"); | |
51041fae BJ |
54 | } |
55 | mlen += 8; | |
4d0a6cbd BJ |
56 | sum = ((sum >> 16) & 0xffff) + (sum & 0xffff); |
57 | w = (u_short *)l; | |
51041fae | 58 | while ((mlen -= 2) >= 0) { |
4d0a6cbd | 59 | asm("movzwl (r7)+,r0; addl2 r0,r8"); |
51041fae BJ |
60 | } |
61 | if (mlen == -1) | |
62 | sum += *(u_char *)w; | |
63 | if (len == 0) | |
64 | break; | |
65 | for (;;) { | |
f248b7ed BJ |
66 | if (m == 0) { |
67 | printf("cksum: out of data"); | |
68 | goto done; | |
69 | } | |
51041fae BJ |
70 | if (m->m_len) |
71 | break; | |
72 | m = m->m_next; | |
73 | } | |
74 | } | |
f248b7ed | 75 | done: |
51041fae BJ |
76 | return(~(sum + (sum >> 16)) & 0xffff); |
77 | } |