* m MUST contain a contiguous IP6 header. * off is an offset where TCP/UDP/ICMP6 header starts. * len is a total length of a transport segment. * (e.g. TCP header + TCP payload) * cov is the number of bytes to be taken into account for the checksum */
| 150 | * cov is the number of bytes to be taken into account for the checksum |
| 151 | */ |
| 152 | int |
| 153 | in6_cksum_partial(struct mbuf *m, u_int8_t nxt, u_int32_t off, |
| 154 | u_int32_t len, u_int32_t cov) |
| 155 | { |
| 156 | struct ip6_hdr *ip6; |
| 157 | u_int16_t *w, scope; |
| 158 | int byte_swapped, mlen; |
| 159 | int sum; |
| 160 | union { |
| 161 | u_int16_t phs[4]; |
| 162 | struct { |
| 163 | u_int32_t ph_len; |
| 164 | u_int8_t ph_zero[3]; |
| 165 | u_int8_t ph_nxt; |
| 166 | } __packed ph; |
| 167 | } uph; |
| 168 | union { |
| 169 | u_int8_t c[2]; |
| 170 | u_int16_t s; |
| 171 | } s_util; |
| 172 | union { |
| 173 | u_int16_t s[2]; |
| 174 | u_int32_t l; |
| 175 | } l_util; |
| 176 | |
| 177 | /* Sanity check. */ |
| 178 | KASSERT(m->m_pkthdr.len >= off + len, ("%s: mbuf len (%d) < off(%d)+" |
| 179 | "len(%d)", __func__, m->m_pkthdr.len, off, len)); |
| 180 | |
| 181 | /* |
| 182 | * First create IP6 pseudo header and calculate a summary. |
| 183 | */ |
| 184 | uph.ph.ph_len = htonl(len); |
| 185 | uph.ph.ph_zero[0] = uph.ph.ph_zero[1] = uph.ph.ph_zero[2] = 0; |
| 186 | uph.ph.ph_nxt = nxt; |
| 187 | |
| 188 | /* Payload length and upper layer identifier. */ |
| 189 | sum = uph.phs[0]; sum += uph.phs[1]; |
| 190 | sum += uph.phs[2]; sum += uph.phs[3]; |
| 191 | |
| 192 | ip6 = mtod(m, struct ip6_hdr *); |
| 193 | |
| 194 | /* IPv6 source address. */ |
| 195 | scope = in6_getscope(&ip6->ip6_src); |
| 196 | w = (u_int16_t *)&ip6->ip6_src; |
| 197 | sum += w[0]; sum += w[1]; sum += w[2]; sum += w[3]; |
| 198 | sum += w[4]; sum += w[5]; sum += w[6]; sum += w[7]; |
| 199 | if (scope != 0) |
| 200 | sum -= scope; |
| 201 | |
| 202 | /* IPv6 destination address. */ |
| 203 | scope = in6_getscope(&ip6->ip6_dst); |
| 204 | w = (u_int16_t *)&ip6->ip6_dst; |
| 205 | sum += w[0]; sum += w[1]; sum += w[2]; sum += w[3]; |
| 206 | sum += w[4]; sum += w[5]; sum += w[6]; sum += w[7]; |
| 207 | if (scope != 0) |
| 208 | sum -= scope; |
| 209 |
no test coverage detected