* Ip input routine. Checksum and byte swap header. If fragmented * try to reassemble. Process options. Pass to next level. */
| 449 | * try to reassemble. Process options. Pass to next level. |
| 450 | */ |
| 451 | void |
| 452 | ip_input(struct mbuf *m) |
| 453 | { |
| 454 | struct rm_priotracker in_ifa_tracker; |
| 455 | struct ip *ip = NULL; |
| 456 | struct in_ifaddr *ia = NULL; |
| 457 | struct ifaddr *ifa; |
| 458 | struct ifnet *ifp; |
| 459 | int checkif, hlen = 0; |
| 460 | uint16_t sum, ip_len; |
| 461 | int dchg = 0; /* dest changed after fw */ |
| 462 | struct in_addr odst; /* original dst address */ |
| 463 | |
| 464 | M_ASSERTPKTHDR(m); |
| 465 | NET_EPOCH_ASSERT(); |
| 466 | |
| 467 | if (m->m_flags & M_FASTFWD_OURS) { |
| 468 | m->m_flags &= ~M_FASTFWD_OURS; |
| 469 | /* Set up some basics that will be used later. */ |
| 470 | ip = mtod(m, struct ip *); |
| 471 | hlen = ip->ip_hl << 2; |
| 472 | ip_len = ntohs(ip->ip_len); |
| 473 | goto ours; |
| 474 | } |
| 475 | |
| 476 | IPSTAT_INC(ips_total); |
| 477 | |
| 478 | if (m->m_pkthdr.len < sizeof(struct ip)) |
| 479 | goto tooshort; |
| 480 | |
| 481 | if (m->m_len < sizeof (struct ip) && |
| 482 | (m = m_pullup(m, sizeof (struct ip))) == NULL) { |
| 483 | IPSTAT_INC(ips_toosmall); |
| 484 | return; |
| 485 | } |
| 486 | ip = mtod(m, struct ip *); |
| 487 | |
| 488 | if (ip->ip_v != IPVERSION) { |
| 489 | IPSTAT_INC(ips_badvers); |
| 490 | goto bad; |
| 491 | } |
| 492 | |
| 493 | hlen = ip->ip_hl << 2; |
| 494 | if (hlen < sizeof(struct ip)) { /* minimum header length */ |
| 495 | IPSTAT_INC(ips_badhlen); |
| 496 | goto bad; |
| 497 | } |
| 498 | if (hlen > m->m_len) { |
| 499 | if ((m = m_pullup(m, hlen)) == NULL) { |
| 500 | IPSTAT_INC(ips_badhlen); |
| 501 | return; |
| 502 | } |
| 503 | ip = mtod(m, struct ip *); |
| 504 | } |
| 505 | |
| 506 | IP_PROBE(receive, NULL, NULL, ip, m->m_pkthdr.rcvif, ip, NULL); |
| 507 | |
| 508 | /* IN_LOOPBACK must not appear on the wire - RFC1122 */ |
no test coverage detected