int in_cksum(struct mbuf *m, int len) { u_int64_t sum = 0; int mlen = 0; int clen = 0; caddr_t addr; union l_util l_util; union q_util q_util; for (; m && len; m = m->m_next) { if (m->m_len == 0) continue; mlen = m->m_len; if (len < mlen) mlen = len; addr = mtod(m, caddr_t); if ((clen ^ (long) addr) & 1) sum += in_cksumdata(addr, mlen) << 8; else sum += in_cksumdata(addr, mlen); clen += mlen; len -= mlen; } REDUCE16; return (~sum & 0xffff); }
int in4_cksum(struct mbuf *m, u_int8_t nxt, int off, int len) { u_int64_t sum = 0; int mlen = 0; int clen = 0; caddr_t addr; union q_util q_util; union l_util l_util; struct ipovly ipov; if (nxt != 0) { #ifdef DEBUG /* pseudo header */ if (off < sizeof(struct ipovly)) panic("in4_cksum: offset too short"); if (m->m_len < sizeof(struct ip)) panic("in4_cksum: bad mbuf chain"); #endif memset(&ipov, 0, sizeof(ipov)); ipov.ih_len = htons(len); ipov.ih_pr = nxt; ipov.ih_src = mtod(m, struct ip *)->ip_src; ipov.ih_dst = mtod(m, struct ip *)->ip_dst; sum += in_cksumdata((caddr_t) &ipov, sizeof(ipov)); } /* skip over unnecessary part */ while (m != NULL && off > 0) { if (m->m_len > off) break; off -= m->m_len; m = m->m_next; } for (; m && len; m = m->m_next, off = 0) { if (m->m_len == 0) continue; mlen = m->m_len - off; if (len < mlen) mlen = len; addr = mtod(m, caddr_t) + off; if ((clen ^ (long) addr) & 1) sum += in_cksumdata(addr, mlen) << 8; else sum += in_cksumdata(addr, mlen); clen += mlen; len -= mlen; } REDUCE16; return (~sum & 0xffff); }
u_int in_cksum_hdr(const struct ip *ip) { u_int64_t sum = in_cksumdata(ip, sizeof(struct ip)); union q_util q_util; union l_util l_util; REDUCE16; return (~sum & 0xffff); }
uint16_t ptclbsum(uint8_t * addr, int len) { uint64_t sum = in_cksumdata(addr, len); union q_util q_util; union l_util l_util; if ((uintptr_t)addr & 1) sum <<= 8; REDUCE16; return cpu_to_be16(sum); }
u_short in_cksum_skip(struct mbuf *m, int len, int skip) { u_int64_t sum = 0; int mlen = 0; int clen = 0; caddr_t addr; union q_util q_util; union l_util l_util; len -= skip; for (; skip && m; m = m->m_next) { if (m->m_len > skip) { mlen = m->m_len - skip; addr = mtod(m, caddr_t) + skip; goto skip_start; } else { skip -= m->m_len; } } for (; m && len; m = m->m_next) { if (m->m_len == 0) continue; mlen = m->m_len; addr = mtod(m, caddr_t); skip_start: if (len < mlen) mlen = len; if ((clen ^ (uintptr_t) addr) & 1) sum += in_cksumdata(addr, mlen) << 8; else sum += in_cksumdata(addr, mlen); clen += mlen; len -= mlen; } REDUCE16; return (~sum & 0xffff); }