Commit | Line | Data |
---|---|---|
93a804a7 SL |
1 | /* ns_cksum.c 1.1 86/01/23 */ |
2 | ||
3 | /* | |
4 | * ns_cksum.c - Xerox Internet Datagram protocol checksum | |
5 | */ | |
6 | #include "types.h" | |
7 | #include "mbuf.h" | |
8 | ||
9 | /* | |
10 | * Perform (slowly) the Xerox Internet checksum algorithm on a | |
11 | * chain of mbufs. This means we add all the 16-bits words, | |
12 | * shifting the sum after each 16-bit add. Ones-complement | |
13 | * arithmetic is required, so we fold the carry bits after | |
14 | * each 16-bit add as well. | |
15 | * If the result is the *no-checksum* value 0xffff, return zero instead. | |
16 | * | |
17 | * Chris Torek <chris@maryland> | |
18 | * James O'Toole <james@maryland> | |
19 | */ | |
20 | u_short | |
21 | ns_cksum(m, len) | |
22 | register struct mbuf *m; | |
23 | register int len; | |
24 | { | |
25 | register int cksum = 0; | |
26 | register int shift = 8; | |
27 | register u_char *p; | |
28 | register int mlen; | |
29 | ||
30 | if (len & 1) | |
31 | printf("ns_cksum: odd length\n"); | |
32 | while (m && len) { | |
33 | p = mtod(m, u_char *); | |
34 | mlen = m->m_len; | |
35 | if ((len -= mlen) < 0) | |
36 | mlen += len, len = 0; | |
37 | while (--mlen >= 0) { | |
38 | cksum += *p++ << shift; | |
39 | if ((shift = 8 - shift) != 0) { | |
40 | cksum <<= 1; | |
41 | cksum = (cksum & 0xffff) + (cksum >> 16); | |
42 | } | |
43 | } | |
44 | m = m->m_next; | |
45 | } | |
46 | #ifdef notdef | |
47 | if (len) | |
48 | printf("ns_cksum: out of data\n"); | |
49 | #endif | |
50 | return (cksum == 0xffff ? 0 : cksum); | |
51 | } |