* Process a received ICMP message. */
| 400 | * Process a received ICMP message. |
| 401 | */ |
| 402 | int |
| 403 | icmp_input(struct mbuf **mp, int *offp, int proto) |
| 404 | { |
| 405 | struct icmp *icp; |
| 406 | struct in_ifaddr *ia; |
| 407 | struct mbuf *m = *mp; |
| 408 | struct ip *ip = mtod(m, struct ip *); |
| 409 | struct sockaddr_in icmpsrc, icmpdst, icmpgw; |
| 410 | int hlen = *offp; |
| 411 | int icmplen = ntohs(ip->ip_len) - *offp; |
| 412 | int i, code; |
| 413 | void (*ctlfunc)(int, struct sockaddr *, void *); |
| 414 | int fibnum; |
| 415 | |
| 416 | NET_EPOCH_ASSERT(); |
| 417 | |
| 418 | *mp = NULL; |
| 419 | |
| 420 | /* |
| 421 | * Locate icmp structure in mbuf, and check |
| 422 | * that not corrupted and of at least minimum length. |
| 423 | */ |
| 424 | #ifdef ICMPPRINTFS |
| 425 | if (icmpprintfs) { |
| 426 | char srcbuf[INET_ADDRSTRLEN]; |
| 427 | char dstbuf[INET_ADDRSTRLEN]; |
| 428 | |
| 429 | printf("icmp_input from %s to %s, len %d\n", |
| 430 | inet_ntoa_r(ip->ip_src, srcbuf), |
| 431 | inet_ntoa_r(ip->ip_dst, dstbuf), icmplen); |
| 432 | } |
| 433 | #endif |
| 434 | if (icmplen < ICMP_MINLEN) { |
| 435 | ICMPSTAT_INC(icps_tooshort); |
| 436 | goto freeit; |
| 437 | } |
| 438 | i = hlen + min(icmplen, ICMP_ADVLENMIN); |
| 439 | if (m->m_len < i && (m = m_pullup(m, i)) == NULL) { |
| 440 | ICMPSTAT_INC(icps_tooshort); |
| 441 | return (IPPROTO_DONE); |
| 442 | } |
| 443 | ip = mtod(m, struct ip *); |
| 444 | m->m_len -= hlen; |
| 445 | m->m_data += hlen; |
| 446 | icp = mtod(m, struct icmp *); |
| 447 | if (in_cksum(m, icmplen)) { |
| 448 | ICMPSTAT_INC(icps_checksum); |
| 449 | goto freeit; |
| 450 | } |
| 451 | m->m_len += hlen; |
| 452 | m->m_data -= hlen; |
| 453 | |
| 454 | #ifdef ICMPPRINTFS |
| 455 | if (icmpprintfs) |
| 456 | printf("icmp_input, type %d code %d\n", icp->icmp_type, |
| 457 | icp->icmp_code); |
| 458 | #endif |
| 459 |
nothing calls this directly
no test coverage detected