* Massage IPv4/IPv6 headers for AH processing. */
| 258 | * Massage IPv4/IPv6 headers for AH processing. |
| 259 | */ |
| 260 | static int |
| 261 | ah_massage_headers(struct mbuf **m0, int proto, int skip, int alg, int out) |
| 262 | { |
| 263 | struct mbuf *m = *m0; |
| 264 | unsigned char *ptr; |
| 265 | int off, count; |
| 266 | |
| 267 | #ifdef INET |
| 268 | struct ip *ip; |
| 269 | #endif /* INET */ |
| 270 | |
| 271 | #ifdef INET6 |
| 272 | struct ip6_ext *ip6e; |
| 273 | struct ip6_hdr ip6; |
| 274 | int ad, alloc, nxt, noff; |
| 275 | #endif /* INET6 */ |
| 276 | |
| 277 | switch (proto) { |
| 278 | #ifdef INET |
| 279 | case AF_INET: |
| 280 | /* |
| 281 | * This is the least painful way of dealing with IPv4 header |
| 282 | * and option processing -- just make sure they're in |
| 283 | * contiguous memory. |
| 284 | */ |
| 285 | *m0 = m = m_pullup(m, skip); |
| 286 | if (m == NULL) { |
| 287 | DPRINTF(("%s: m_pullup failed\n", __func__)); |
| 288 | return ENOBUFS; |
| 289 | } |
| 290 | |
| 291 | /* Fix the IP header */ |
| 292 | ip = mtod(m, struct ip *); |
| 293 | if (V_ah_cleartos) |
| 294 | ip->ip_tos = 0; |
| 295 | ip->ip_ttl = 0; |
| 296 | ip->ip_sum = 0; |
| 297 | ip->ip_off = htons(0); |
| 298 | |
| 299 | ptr = mtod(m, unsigned char *); |
| 300 | |
| 301 | /* IPv4 option processing */ |
| 302 | for (off = sizeof(struct ip); off < skip;) { |
| 303 | if (ptr[off] == IPOPT_EOL || ptr[off] == IPOPT_NOP || |
| 304 | off + 1 < skip) |
| 305 | ; |
| 306 | else { |
| 307 | DPRINTF(("%s: illegal IPv4 option length for " |
| 308 | "option %d\n", __func__, ptr[off])); |
| 309 | |
| 310 | m_freem(m); |
| 311 | return EINVAL; |
| 312 | } |
| 313 | |
| 314 | switch (ptr[off]) { |
| 315 | case IPOPT_EOL: |
| 316 | off = skip; /* End the loop. */ |
| 317 | break; |
no test coverage detected