* Process a received ICMP6 message. */
| 394 | * Process a received ICMP6 message. |
| 395 | */ |
| 396 | int |
| 397 | icmp6_input(struct mbuf **mp, int *offp, int proto) |
| 398 | { |
| 399 | struct mbuf *m, *n; |
| 400 | struct ifnet *ifp; |
| 401 | struct ip6_hdr *ip6, *nip6; |
| 402 | struct icmp6_hdr *icmp6, *nicmp6; |
| 403 | char ip6bufs[INET6_ADDRSTRLEN], ip6bufd[INET6_ADDRSTRLEN]; |
| 404 | int code, error, icmp6len, ip6len, noff, off, sum; |
| 405 | |
| 406 | NET_EPOCH_ASSERT(); |
| 407 | |
| 408 | m = *mp; |
| 409 | off = *offp; |
| 410 | |
| 411 | if (m->m_len < off + sizeof(struct icmp6_hdr)) { |
| 412 | m = m_pullup(m, off + sizeof(struct icmp6_hdr)); |
| 413 | if (m == NULL) { |
| 414 | IP6STAT_INC(ip6s_exthdrtoolong); |
| 415 | *mp = m; |
| 416 | return (IPPROTO_DONE); |
| 417 | } |
| 418 | } |
| 419 | |
| 420 | /* |
| 421 | * Locate icmp6 structure in mbuf, and check |
| 422 | * that not corrupted and of at least minimum length |
| 423 | */ |
| 424 | |
| 425 | icmp6len = m->m_pkthdr.len - off; |
| 426 | if (icmp6len < sizeof(struct icmp6_hdr)) { |
| 427 | ICMP6STAT_INC(icp6s_tooshort); |
| 428 | goto freeit; |
| 429 | } |
| 430 | |
| 431 | ip6 = mtod(m, struct ip6_hdr *); |
| 432 | ifp = m->m_pkthdr.rcvif; |
| 433 | /* |
| 434 | * Check multicast group membership. |
| 435 | * Note: SSM filters are not applied for ICMPv6 traffic. |
| 436 | */ |
| 437 | if (IN6_IS_ADDR_MULTICAST(&ip6->ip6_dst)) { |
| 438 | struct in6_multi *inm; |
| 439 | |
| 440 | inm = in6m_lookup(ifp, &ip6->ip6_dst); |
| 441 | if (inm == NULL) { |
| 442 | IP6STAT_INC(ip6s_notmember); |
| 443 | in6_ifstat_inc(m->m_pkthdr.rcvif, ifs6_in_discard); |
| 444 | goto freeit; |
| 445 | } |
| 446 | } |
| 447 | |
| 448 | /* Calculate the checksum. */ |
| 449 | icmp6 = (struct icmp6_hdr *)((caddr_t)ip6 + off); |
| 450 | code = icmp6->icmp6_code; |
| 451 | if ((sum = in6_cksum(m, IPPROTO_ICMPV6, off, icmp6len)) != 0) { |
| 452 | nd6log((LOG_ERR, |
| 453 | "ICMP6 checksum error(%d|%x) %s\n", |
nothing calls this directly
no test coverage detected