-ocksum(m, len)
-register struct mbuf *m;
-register len;
-{
- register unsigned short *w;
- register unsigned long sum;
- register mlen;
-COUNT(OCKSUM);
-
- w = (unsigned short *)((int)m + m->m_off);
- mlen = m->m_len;
- sum = 0;
-
- for (; len > 0; len -= 2, mlen -= 2) {
-
-try: if (mlen > 1) { /* can get a word */
-
- if (len > 1) {
- sum += *(w++);
-
- } else /* trailing odd byte */
-
- sum += *((char *)w) & 0xff;
-
- } else if (mlen > 0) { /* last byte of mbuf */
-
- sum += *((char *)w) & 0xff;
-
- if (len > 1) {
-
- /* get next good mbuf for hi byte */
-
- while ((m = m->m_next) != 0 &&
- (mlen = m->m_len + 1) == 1);
- if (m != 0) {
- w = (unsigned short *)((int)m + m->m_off);
- sum += (*((char *)w) & 0xff) << 8;
- w = (unsigned short *)((int)w + 1);
- } else
- len = 0; /* force loop exit */
- }
-
- } else { /* end of mbuf, get next and try again */
-
- while ((m = m->m_next) != 0 && (mlen = m->m_len) == 0);
- if (m != 0) {
- w = (unsigned short *)((int)m + m->m_off);
- goto try;
- } else
- break;
- }
- }
-
- /* add in one's complement carry */
-
- sum = (sum + (sum >> 16)) & 0xffff;
- return(~sum & 0xffff);
-}