| 48 | #define REDUCE {l_util.l = sum; sum = l_util.s[0] + l_util.s[1]; ADDCARRY(sum);} |
| 49 | |
| 50 | int |
| 51 | in_cksum(struct mbuf *m, int len) |
| 52 | { |
| 53 | u_short *w; |
| 54 | int sum = 0; |
| 55 | int mlen = 0; |
| 56 | int byte_swapped = 0; |
| 57 | |
| 58 | union { |
| 59 | char c[2]; |
| 60 | u_short s; |
| 61 | } s_util; |
| 62 | union { |
| 63 | u_short s[2]; |
| 64 | long l; |
| 65 | } l_util; |
| 66 | |
| 67 | for (;m && len; m = m->m_next) { |
| 68 | if (m->m_len == 0) |
| 69 | continue; |
| 70 | w = mtod(m, u_short *); |
| 71 | if (mlen == -1) { |
| 72 | /* |
| 73 | * The first byte of this mbuf is the continuation |
| 74 | * of a word spanning between this mbuf and the |
| 75 | * last mbuf. |
| 76 | * |
| 77 | * s_util.c[0] is already saved when scanning previous |
| 78 | * mbuf. |
| 79 | */ |
| 80 | s_util.c[1] = *(char *)w; |
| 81 | sum += s_util.s; |
| 82 | w = (u_short *)((char *)w + 1); |
| 83 | mlen = m->m_len - 1; |
| 84 | len--; |
| 85 | } else |
| 86 | mlen = m->m_len; |
| 87 | if (len < mlen) |
| 88 | mlen = len; |
| 89 | len -= mlen; |
| 90 | /* |
| 91 | * Force to even boundary. |
| 92 | */ |
| 93 | if ((1 & (uintptr_t) w) && (mlen > 0)) { |
| 94 | REDUCE; |
| 95 | sum <<= 8; |
| 96 | s_util.c[0] = *(u_char *)w; |
| 97 | w = (u_short *)((char *)w + 1); |
| 98 | mlen--; |
| 99 | byte_swapped = 1; |
| 100 | } |
| 101 | /* |
| 102 | * Unroll the loop to make overhead from |
| 103 | * branches &c small. |
| 104 | */ |
| 105 | while ((mlen -= 32) >= 0) { |
| 106 | sum += w[0]; sum += w[1]; sum += w[2]; sum += w[3]; |
| 107 | sum += w[4]; sum += w[5]; sum += w[6]; sum += w[7]; |
no test coverage detected