- uint32_t adj = m_sum16(m, start, len);
- if (adj >= sum)
- sum = ~(adj - sum) & 0xffff;
+ struct mbuf *m0 = m;
+ uint32_t extra = m_sum16(m, bytes, len);
+ uint32_t off = bytes, off0 = off;
+
+ while (off > 0) {
+ if (__improbable(m == NULL)) {
+ panic("%s: invalid mbuf chain %p [off %u, "
+ "len %u]", __func__, m0, off0, len);
+ /* NOTREACHED */
+ }
+ if (off < m->m_len)
+ break;
+ off -= m->m_len;
+ m = m->m_next;
+ }
+
+ /* if we started on odd-alignment, swap the value */
+ if ((uintptr_t)(mtod(m, uint8_t *) + off) & 1)
+ total_sub += ((extra << 8) & 0xffff) | (extra >> 8);
+ else
+ total_sub += extra;
+
+ total_sub = (total_sub >> 16) + (total_sub & 0xffff);
+ }
+
+ /*
+ * 1's complement subtract any extraneous octets.
+ */
+ if (total_sub != 0) {
+ if (total_sub >= sum)
+ sum = ~(total_sub - sum) & 0xffff;