* Perform basic checks on header size since * pfil assumes ip_input has already processed * it for it. Cut-and-pasted from ip_input.c. * Given how simple the IPv6 version is, * does the IPv4 version really need to be * this complicated? * * XXX Should we update ipstat here, or not? * XXX Right now we update ipstat but not * XXX csum_counter. */
| 3412 | * XXX csum_counter. |
| 3413 | */ |
| 3414 | static int |
| 3415 | bridge_ip_checkbasic(struct mbuf **mp) |
| 3416 | { |
| 3417 | struct mbuf *m = *mp; |
| 3418 | struct ip *ip; |
| 3419 | int len, hlen; |
| 3420 | u_short sum; |
| 3421 | |
| 3422 | if (*mp == NULL) |
| 3423 | return (-1); |
| 3424 | |
| 3425 | if (IP_HDR_ALIGNED_P(mtod(m, caddr_t)) == 0) { |
| 3426 | if ((m = m_copyup(m, sizeof(struct ip), |
| 3427 | (max_linkhdr + 3) & ~3)) == NULL) { |
| 3428 | /* XXXJRT new stat, please */ |
| 3429 | KMOD_IPSTAT_INC(ips_toosmall); |
| 3430 | goto bad; |
| 3431 | } |
| 3432 | } else if (__predict_false(m->m_len < sizeof (struct ip))) { |
| 3433 | if ((m = m_pullup(m, sizeof (struct ip))) == NULL) { |
| 3434 | KMOD_IPSTAT_INC(ips_toosmall); |
| 3435 | goto bad; |
| 3436 | } |
| 3437 | } |
| 3438 | ip = mtod(m, struct ip *); |
| 3439 | if (ip == NULL) goto bad; |
| 3440 | |
| 3441 | if (ip->ip_v != IPVERSION) { |
| 3442 | KMOD_IPSTAT_INC(ips_badvers); |
| 3443 | goto bad; |
| 3444 | } |
| 3445 | hlen = ip->ip_hl << 2; |
| 3446 | if (hlen < sizeof(struct ip)) { /* minimum header length */ |
| 3447 | KMOD_IPSTAT_INC(ips_badhlen); |
| 3448 | goto bad; |
| 3449 | } |
| 3450 | if (hlen > m->m_len) { |
| 3451 | if ((m = m_pullup(m, hlen)) == NULL) { |
| 3452 | KMOD_IPSTAT_INC(ips_badhlen); |
| 3453 | goto bad; |
| 3454 | } |
| 3455 | ip = mtod(m, struct ip *); |
| 3456 | if (ip == NULL) goto bad; |
| 3457 | } |
| 3458 | |
| 3459 | if (m->m_pkthdr.csum_flags & CSUM_IP_CHECKED) { |
| 3460 | sum = !(m->m_pkthdr.csum_flags & CSUM_IP_VALID); |
| 3461 | } else { |
| 3462 | if (hlen == sizeof(struct ip)) { |
| 3463 | sum = in_cksum_hdr(ip); |
| 3464 | } else { |
| 3465 | sum = in_cksum(m, hlen); |
| 3466 | } |
| 3467 | } |
| 3468 | if (sum) { |
| 3469 | KMOD_IPSTAT_INC(ips_badsum); |
| 3470 | goto bad; |
| 3471 | } |
no test coverage detected