1 /* $OpenBSD: ip_icmp.c,v 1.45 2002/01/21 05:33:14 itojun Exp $ */ 2 /* $NetBSD: ip_icmp.c,v 1.19 1996/02/13 23:42:22 christos Exp $ */ 3 4 /* 5 * Copyright (c) 1982, 1986, 1988, 1993 6 * The Regents of the University of California. All rights reserved. 7 * 8 * Redistribution and use in source and binary forms, with or without 9 * modification, are permitted provided that the following conditions 10 * are met: 11 * 1. Redistributions of source code must retain the above copyright 12 * notice, this list of conditions and the following disclaimer. 13 * 2. Redistributions in binary form must reproduce the above copyright 14 * notice, this list of conditions and the following disclaimer in the 15 * documentation and/or other materials provided with the distribution. 16 * 3. All advertising materials mentioning features or use of this software 17 * must display the following acknowledgement: 18 * This product includes software developed by the University of 19 * California, Berkeley and its contributors. 20 * 4. Neither the name of the University nor the names of its contributors 21 * may be used to endorse or promote products derived from this software 22 * without specific prior written permission. 23 * 24 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 25 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 26 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 27 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 28 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 29 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 30 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 31 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 32 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 33 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 34 * SUCH DAMAGE. 35 * 36 * @(#)COPYRIGHT 1.1 (NRL) 17 January 1995 37 * 38 * NRL grants permission for redistribution and use in source and binary 39 * forms, with or without modification, of the software and documentation 40 * created at NRL provided that the following conditions are met: 41 * 42 * 1. Redistributions of source code must retain the above copyright 43 * notice, this list of conditions and the following disclaimer. 44 * 2. Redistributions in binary form must reproduce the above copyright 45 * notice, this list of conditions and the following disclaimer in the 46 * documentation and/or other materials provided with the distribution. 47 * 3. All advertising materials mentioning features or use of this software 48 * must display the following acknowledgements: 49 * This product includes software developed by the University of 50 * California, Berkeley and its contributors. 51 * This product includes software developed at the Information 52 * Technology Division, US Naval Research Laboratory. 53 * 4. Neither the name of the NRL nor the names of its contributors 54 * may be used to endorse or promote products derived from this software 55 * without specific prior written permission. 56 * 57 * THE SOFTWARE PROVIDED BY NRL IS PROVIDED BY NRL AND CONTRIBUTORS ``AS 58 * IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 59 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A 60 * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL NRL OR 61 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 62 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 63 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 64 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 65 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 66 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 67 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 68 * 69 * The views and conclusions contained in the software and documentation 70 * are those of the authors and should not be interpreted as representing 71 * official policies, either expressed or implied, of the US Naval 72 * Research Laboratory (NRL). 73 */ 74 75 #include <sys/param.h> 76 #include <sys/systm.h> 77 #include <sys/mbuf.h> 78 #include <sys/protosw.h> 79 #include <sys/socket.h> 80 #include <sys/sysctl.h> 81 82 #include <net/if.h> 83 #include <net/route.h> 84 85 #include <netinet/in.h> 86 #include <netinet/in_systm.h> 87 #include <netinet/in_var.h> 88 #include <netinet/ip.h> 89 #include <netinet/ip_icmp.h> 90 #include <netinet/ip_var.h> 91 #include <netinet/icmp_var.h> 92 93 /* 94 * ICMP routines: error generation, receive packet processing, and 95 * routines to turnaround packets back to the originator, and 96 * host table maintenance routines. 97 */ 98 99 int icmpmaskrepl = 0; 100 int icmpbmcastecho = 0; 101 #ifdef ICMPPRINTFS 102 int icmpprintfs = 0; 103 #endif 104 int icmperrppslim = 100; 105 int icmperrpps_count = 0; 106 struct timeval icmperrppslim_last; 107 int icmp_rediraccept = 1; 108 int icmp_redirtimeout = 10 * 60; 109 static struct rttimer_queue *icmp_redirect_timeout_q = NULL; 110 111 void icmp_mtudisc_timeout __P((struct rtentry *, struct rttimer *)); 112 int icmp_ratelimit __P((const struct in_addr *, const int, const int)); 113 static void icmp_redirect_timeout __P((struct rtentry *, struct rttimer *)); 114 115 extern struct protosw inetsw[]; 116 117 void 118 icmp_init() 119 { 120 /* 121 * This is only useful if the user initializes redirtimeout to 122 * something other than zero. 123 */ 124 if (icmp_redirtimeout != 0) { 125 icmp_redirect_timeout_q = 126 rt_timer_queue_create(icmp_redirtimeout); 127 } 128 } 129 130 /* 131 * Generate an error packet of type error 132 * in response to bad packet ip. 133 * 134 * The ip packet inside has ip_off and ip_len in host byte order. 135 */ 136 void 137 icmp_error(n, type, code, dest, destifp) 138 struct mbuf *n; 139 int type, code; 140 n_long dest; 141 struct ifnet *destifp; 142 { 143 register struct ip *oip = mtod(n, struct ip *), *nip; 144 register unsigned oiplen = oip->ip_hl << 2; 145 register struct icmp *icp; 146 struct mbuf *m; 147 struct m_tag *mtag; 148 unsigned icmplen, mblen; 149 150 #ifdef ICMPPRINTFS 151 if (icmpprintfs) 152 printf("icmp_error(%x, %d, %d)\n", oip, type, code); 153 #endif 154 if (type != ICMP_REDIRECT) 155 icmpstat.icps_error++; 156 /* 157 * Don't send error if not the first fragment of message. 158 * Don't error if the old packet protocol was ICMP 159 * error message, only known informational types. 160 */ 161 if (oip->ip_off & IP_OFFMASK) 162 goto freeit; 163 if (oip->ip_p == IPPROTO_ICMP && type != ICMP_REDIRECT && 164 n->m_len >= oiplen + ICMP_MINLEN && 165 !ICMP_INFOTYPE(((struct icmp *)((caddr_t)oip + oiplen))->icmp_type)) { 166 icmpstat.icps_oldicmp++; 167 goto freeit; 168 } 169 /* Don't send error in response to a multicast or broadcast packet */ 170 if (n->m_flags & (M_BCAST|M_MCAST)) 171 goto freeit; 172 173 /* 174 * First, do a rate limitation check. 175 */ 176 if (icmp_ratelimit(&oip->ip_src, type, code)) { 177 /* XXX stat */ 178 goto freeit; 179 } 180 181 /* 182 * Now, formulate icmp message 183 */ 184 icmplen = oiplen + min(8, oip->ip_len); 185 /* 186 * Defend against mbuf chains shorter than oip->ip_len: 187 */ 188 mblen = 0; 189 for (m = n; m && (mblen < icmplen); m = m->m_next) 190 mblen += m->m_len; 191 icmplen = min(mblen, icmplen); 192 193 /* 194 * As we are not required to return everything we have, 195 * we return whatever we can return at ease. 196 * 197 * Note that ICMP datagrams longer than 576 octets are out of spec 198 * according to RFC1812; 199 */ 200 201 KASSERT(ICMP_MINLEN <= MCLBYTES); 202 203 if (icmplen + ICMP_MINLEN > MCLBYTES) 204 icmplen = MCLBYTES - ICMP_MINLEN - sizeof (struct ip); 205 206 m = m_gethdr(M_DONTWAIT, MT_HEADER); 207 if (m && (sizeof (struct ip) + icmplen + ICMP_MINLEN > MHLEN)) { 208 MCLGET(m, M_DONTWAIT); 209 if ((m->m_flags & M_EXT) == 0) { 210 m_freem(m); 211 m = NULL; 212 } 213 } 214 if (m == NULL) 215 goto freeit; 216 m->m_len = icmplen + ICMP_MINLEN; 217 if ((m->m_flags & M_EXT) == 0) 218 MH_ALIGN(m, m->m_len); 219 icp = mtod(m, struct icmp *); 220 if ((u_int)type > ICMP_MAXTYPE) 221 panic("icmp_error"); 222 icmpstat.icps_outhist[type]++; 223 icp->icmp_type = type; 224 if (type == ICMP_REDIRECT) 225 icp->icmp_gwaddr.s_addr = dest; 226 else { 227 icp->icmp_void = 0; 228 /* 229 * The following assignments assume an overlay with the 230 * zeroed icmp_void field. 231 */ 232 if (type == ICMP_PARAMPROB) { 233 icp->icmp_pptr = code; 234 code = 0; 235 } else if (type == ICMP_UNREACH && 236 code == ICMP_UNREACH_NEEDFRAG && destifp) 237 icp->icmp_nextmtu = htons(destifp->if_mtu); 238 } 239 240 HTONS(oip->ip_off); 241 HTONS(oip->ip_len); 242 icp->icmp_code = code; 243 m_copydata(n, 0, icmplen, (caddr_t)&icp->icmp_ip); 244 nip = &icp->icmp_ip; 245 246 /* 247 * Now, copy old ip header (without options) 248 * in front of icmp message. 249 */ 250 if ((m->m_flags & M_EXT) == 0 && 251 m->m_data - sizeof(struct ip) < m->m_pktdat) 252 panic("icmp len"); 253 m->m_data -= sizeof(struct ip); 254 m->m_len += sizeof(struct ip); 255 m->m_pkthdr.len = m->m_len; 256 m->m_pkthdr.rcvif = n->m_pkthdr.rcvif; 257 nip = mtod(m, struct ip *); 258 /* ip_v set in ip_output */ 259 nip->ip_hl = sizeof(struct ip) >> 2; 260 nip->ip_tos = 0; 261 nip->ip_len = m->m_len; 262 /* ip_id set in ip_output */ 263 nip->ip_off = 0; 264 /* ip_ttl set in icmp_reflect */ 265 nip->ip_p = IPPROTO_ICMP; 266 nip->ip_src = oip->ip_src; 267 nip->ip_dst = oip->ip_dst; 268 /* move PF_GENERATED m_tag to new packet, if it exists */ 269 mtag = m_tag_find(n, PACKET_TAG_PF_GENERATED, NULL); 270 if (mtag != NULL) { 271 m_tag_unlink(n, mtag); 272 m_tag_prepend(m, mtag); 273 } 274 icmp_reflect(m); 275 276 freeit: 277 m_freem(n); 278 } 279 280 static struct sockaddr_in icmpsrc = { sizeof (struct sockaddr_in), AF_INET }; 281 static struct sockaddr_in icmpdst = { sizeof (struct sockaddr_in), AF_INET }; 282 static struct sockaddr_in icmpgw = { sizeof (struct sockaddr_in), AF_INET }; 283 struct sockaddr_in icmpmask = { 8, 0 }; 284 285 /* 286 * Process a received ICMP message. 287 */ 288 void 289 #if __STDC__ 290 icmp_input(struct mbuf *m, ...) 291 #else 292 icmp_input(m, va_alist) 293 struct mbuf *m; 294 va_dcl 295 #endif 296 { 297 register struct icmp *icp; 298 register struct ip *ip = mtod(m, struct ip *); 299 int icmplen = ip->ip_len; 300 register int i; 301 struct in_ifaddr *ia; 302 void *(*ctlfunc) __P((int, struct sockaddr *, void *)); 303 int code; 304 extern u_char ip_protox[]; 305 int hlen; 306 va_list ap; 307 struct rtentry *rt; 308 309 va_start(ap, m); 310 hlen = va_arg(ap, int); 311 va_end(ap); 312 313 /* 314 * Locate icmp structure in mbuf, and check 315 * that not corrupted and of at least minimum length. 316 */ 317 #ifdef ICMPPRINTFS 318 if (icmpprintfs) { 319 char buf[4*sizeof "123"]; 320 321 strcpy(buf, inet_ntoa(ip->ip_dst)); 322 printf("icmp_input from %s to %s, len %d\n", 323 inet_ntoa(ip->ip_src), buf, icmplen); 324 } 325 #endif 326 if (icmplen < ICMP_MINLEN) { 327 icmpstat.icps_tooshort++; 328 goto freeit; 329 } 330 i = hlen + min(icmplen, ICMP_ADVLENMIN); 331 if (m->m_len < i && (m = m_pullup(m, i)) == NULL) { 332 icmpstat.icps_tooshort++; 333 return; 334 } 335 ip = mtod(m, struct ip *); 336 m->m_len -= hlen; 337 m->m_data += hlen; 338 icp = mtod(m, struct icmp *); 339 if (in_cksum(m, icmplen)) { 340 icmpstat.icps_checksum++; 341 goto freeit; 342 } 343 m->m_len += hlen; 344 m->m_data -= hlen; 345 346 #ifdef ICMPPRINTFS 347 /* 348 * Message type specific processing. 349 */ 350 if (icmpprintfs) 351 printf("icmp_input, type %d code %d\n", icp->icmp_type, 352 icp->icmp_code); 353 #endif 354 if (icp->icmp_type > ICMP_MAXTYPE) 355 goto raw; 356 icmpstat.icps_inhist[icp->icmp_type]++; 357 code = icp->icmp_code; 358 switch (icp->icmp_type) { 359 360 case ICMP_UNREACH: 361 switch (code) { 362 case ICMP_UNREACH_NET: 363 case ICMP_UNREACH_HOST: 364 case ICMP_UNREACH_PROTOCOL: 365 case ICMP_UNREACH_PORT: 366 case ICMP_UNREACH_SRCFAIL: 367 code += PRC_UNREACH_NET; 368 break; 369 370 case ICMP_UNREACH_NEEDFRAG: 371 code = PRC_MSGSIZE; 372 break; 373 374 case ICMP_UNREACH_NET_UNKNOWN: 375 case ICMP_UNREACH_NET_PROHIB: 376 case ICMP_UNREACH_TOSNET: 377 code = PRC_UNREACH_NET; 378 break; 379 380 case ICMP_UNREACH_HOST_UNKNOWN: 381 case ICMP_UNREACH_ISOLATED: 382 case ICMP_UNREACH_HOST_PROHIB: 383 case ICMP_UNREACH_TOSHOST: 384 case ICMP_UNREACH_FILTER_PROHIB: 385 case ICMP_UNREACH_HOST_PRECEDENCE: 386 case ICMP_UNREACH_PRECEDENCE_CUTOFF: 387 code = PRC_UNREACH_HOST; 388 break; 389 390 default: 391 goto badcode; 392 } 393 goto deliver; 394 395 case ICMP_TIMXCEED: 396 if (code > 1) 397 goto badcode; 398 code += PRC_TIMXCEED_INTRANS; 399 goto deliver; 400 401 case ICMP_PARAMPROB: 402 if (code > 1) 403 goto badcode; 404 code = PRC_PARAMPROB; 405 goto deliver; 406 407 case ICMP_SOURCEQUENCH: 408 if (code) 409 goto badcode; 410 code = PRC_QUENCH; 411 deliver: 412 /* Free packet atttributes */ 413 if (m->m_flags & M_PKTHDR) 414 m_tag_delete_chain(m, NULL); 415 416 /* 417 * Problem with datagram; advise higher level routines. 418 */ 419 if (icmplen < ICMP_ADVLENMIN || icmplen < ICMP_ADVLEN(icp) || 420 icp->icmp_ip.ip_hl < (sizeof(struct ip) >> 2)) { 421 icmpstat.icps_badlen++; 422 goto freeit; 423 } 424 if (IN_MULTICAST(icp->icmp_ip.ip_dst.s_addr)) 425 goto badcode; 426 NTOHS(icp->icmp_ip.ip_len); 427 #ifdef INET6 428 /* Get more contiguous data for a v6 in v4 ICMP message. */ 429 if (icp->icmp_ip.ip_p == IPPROTO_IPV6) { 430 if (icmplen < ICMP_V6ADVLENMIN || 431 icmplen < ICMP_V6ADVLEN(icp)) { 432 icmpstat.icps_badlen++; 433 goto freeit; 434 } else { 435 if ((m = m_pullup(m, (ip->ip_hl << 2) + 436 ICMP_V6ADVLEN(icp))) == NULL) { 437 icmpstat.icps_tooshort++; 438 return; 439 } 440 ip = mtod(m, struct ip *); 441 icp = (struct icmp *)(m->m_data + (ip->ip_hl << 2)); 442 } 443 } 444 #endif /* INET6 */ 445 #ifdef ICMPPRINTFS 446 if (icmpprintfs) 447 printf("deliver to protocol %d\n", icp->icmp_ip.ip_p); 448 #endif 449 icmpsrc.sin_addr = icp->icmp_ip.ip_dst; 450 /* 451 * XXX if the packet contains [IPv4 AH TCP], we can't make a 452 * notification to TCP layer. 453 */ 454 ctlfunc = inetsw[ip_protox[icp->icmp_ip.ip_p]].pr_ctlinput; 455 if (ctlfunc) 456 (*ctlfunc)(code, sintosa(&icmpsrc), &icp->icmp_ip); 457 break; 458 459 badcode: 460 icmpstat.icps_badcode++; 461 break; 462 463 case ICMP_ECHO: 464 if (!icmpbmcastecho && 465 (m->m_flags & (M_MCAST | M_BCAST)) != 0) { 466 icmpstat.icps_bmcastecho++; 467 break; 468 } 469 icp->icmp_type = ICMP_ECHOREPLY; 470 goto reflect; 471 472 case ICMP_TSTAMP: 473 if (!icmpbmcastecho && 474 (m->m_flags & (M_MCAST | M_BCAST)) != 0) { 475 icmpstat.icps_bmcastecho++; 476 break; 477 } 478 if (icmplen < ICMP_TSLEN) { 479 icmpstat.icps_badlen++; 480 break; 481 } 482 icp->icmp_type = ICMP_TSTAMPREPLY; 483 icp->icmp_rtime = iptime(); 484 icp->icmp_ttime = icp->icmp_rtime; /* bogus, do later! */ 485 goto reflect; 486 487 case ICMP_MASKREQ: 488 if (icmpmaskrepl == 0) 489 break; 490 /* 491 * We are not able to respond with all ones broadcast 492 * unless we receive it over a point-to-point interface. 493 */ 494 if (icmplen < ICMP_MASKLEN) { 495 icmpstat.icps_badlen++; 496 break; 497 } 498 if (ip->ip_dst.s_addr == INADDR_BROADCAST || 499 ip->ip_dst.s_addr == INADDR_ANY) 500 icmpdst.sin_addr = ip->ip_src; 501 else 502 icmpdst.sin_addr = ip->ip_dst; 503 if (m->m_pkthdr.rcvif == NULL) 504 break; 505 ia = ifatoia(ifaof_ifpforaddr(sintosa(&icmpdst), 506 m->m_pkthdr.rcvif)); 507 if (ia == 0) 508 break; 509 icp->icmp_type = ICMP_MASKREPLY; 510 icp->icmp_mask = ia->ia_sockmask.sin_addr.s_addr; 511 if (ip->ip_src.s_addr == 0) { 512 if (ia->ia_ifp->if_flags & IFF_BROADCAST) 513 ip->ip_src = ia->ia_broadaddr.sin_addr; 514 else if (ia->ia_ifp->if_flags & IFF_POINTOPOINT) 515 ip->ip_src = ia->ia_dstaddr.sin_addr; 516 } 517 reflect: 518 /* Free packet atttributes */ 519 if (m->m_flags & M_PKTHDR) 520 m_tag_delete_chain(m, NULL); 521 522 ip->ip_len += hlen; /* since ip_input deducts this */ 523 icmpstat.icps_reflect++; 524 icmpstat.icps_outhist[icp->icmp_type]++; 525 icmp_reflect(m); 526 return; 527 528 case ICMP_REDIRECT: 529 /* Free packet atttributes */ 530 if (m->m_flags & M_PKTHDR) 531 m_tag_delete_chain(m, NULL); 532 if (icmp_rediraccept == 0) 533 goto freeit; 534 if (code > 3) 535 goto badcode; 536 if (icmplen < ICMP_ADVLENMIN || icmplen < ICMP_ADVLEN(icp) || 537 icp->icmp_ip.ip_hl < (sizeof(struct ip) >> 2)) { 538 icmpstat.icps_badlen++; 539 break; 540 } 541 /* 542 * Short circuit routing redirects to force 543 * immediate change in the kernel's routing 544 * tables. The message is also handed to anyone 545 * listening on a raw socket (e.g. the routing 546 * daemon for use in updating its tables). 547 */ 548 icmpgw.sin_addr = ip->ip_src; 549 icmpdst.sin_addr = icp->icmp_gwaddr; 550 #ifdef ICMPPRINTFS 551 if (icmpprintfs) { 552 char buf[4 * sizeof "123"]; 553 strcpy(buf, inet_ntoa(icp->icmp_ip.ip_dst)); 554 555 printf("redirect dst %s to %s\n", 556 buf, inet_ntoa(icp->icmp_gwaddr)); 557 } 558 #endif 559 icmpsrc.sin_addr = icp->icmp_ip.ip_dst; 560 rt = NULL; 561 rtredirect(sintosa(&icmpsrc), sintosa(&icmpdst), 562 (struct sockaddr *)0, RTF_GATEWAY | RTF_HOST, 563 sintosa(&icmpgw), (struct rtentry **)&rt); 564 if (rt != NULL && icmp_redirtimeout != 0) { 565 (void)rt_timer_add(rt, icmp_redirect_timeout, 566 icmp_redirect_timeout_q); 567 } 568 if (rt != NULL) 569 rtfree(rt); 570 pfctlinput(PRC_REDIRECT_HOST, sintosa(&icmpsrc)); 571 break; 572 573 /* 574 * No kernel processing for the following; 575 * just fall through to send to raw listener. 576 */ 577 case ICMP_ECHOREPLY: 578 case ICMP_ROUTERADVERT: 579 case ICMP_ROUTERSOLICIT: 580 case ICMP_TSTAMPREPLY: 581 case ICMP_IREQREPLY: 582 case ICMP_MASKREPLY: 583 case ICMP_TRACEROUTE: 584 case ICMP_DATACONVERR: 585 case ICMP_MOBILE_REDIRECT: 586 case ICMP_IPV6_WHEREAREYOU: 587 case ICMP_IPV6_IAMHERE: 588 case ICMP_MOBILE_REGREQUEST: 589 case ICMP_MOBILE_REGREPLY: 590 case ICMP_PHOTURIS: 591 default: 592 break; 593 } 594 595 raw: 596 rip_input(m); 597 return; 598 599 freeit: 600 m_freem(m); 601 } 602 603 /* 604 * Reflect the ip packet back to the source 605 */ 606 void 607 icmp_reflect(m) 608 struct mbuf *m; 609 { 610 register struct ip *ip = mtod(m, struct ip *); 611 register struct in_ifaddr *ia; 612 struct in_addr t; 613 struct mbuf *opts = 0; 614 int optlen = (ip->ip_hl << 2) - sizeof(struct ip); 615 616 if (!in_canforward(ip->ip_src) && 617 ((ip->ip_src.s_addr & IN_CLASSA_NET) != 618 htonl(IN_LOOPBACKNET << IN_CLASSA_NSHIFT))) { 619 m_freem(m); /* Bad return address */ 620 goto done; /* ip_output() will check for broadcast */ 621 } 622 t = ip->ip_dst; 623 ip->ip_dst = ip->ip_src; 624 /* 625 * If the incoming packet was addressed directly to us, 626 * use dst as the src for the reply. Otherwise (broadcast 627 * or anonymous), use the address which corresponds 628 * to the incoming interface. 629 */ 630 for (ia = in_ifaddr.tqh_first; ia; ia = ia->ia_list.tqe_next) { 631 if (t.s_addr == ia->ia_addr.sin_addr.s_addr) 632 break; 633 if ((ia->ia_ifp->if_flags & IFF_BROADCAST) && 634 t.s_addr == ia->ia_broadaddr.sin_addr.s_addr) 635 break; 636 } 637 icmpdst.sin_addr = t; 638 if ((ia == (struct in_ifaddr *)0) && (m->m_pkthdr.rcvif != NULL)) 639 ia = ifatoia(ifaof_ifpforaddr(sintosa(&icmpdst), 640 m->m_pkthdr.rcvif)); 641 /* 642 * The following happens if the packet was not addressed to us, 643 * and was received on an interface with no IP address. 644 */ 645 if (ia == (struct in_ifaddr *)0) { 646 struct sockaddr_in *dst; 647 struct route ro; 648 649 bzero((caddr_t) &ro, sizeof(ro)); 650 dst = satosin(&ro.ro_dst); 651 dst->sin_family = AF_INET; 652 dst->sin_len = sizeof(*dst); 653 dst->sin_addr = t; 654 655 rtalloc(&ro); 656 if (ro.ro_rt == 0) 657 { 658 ipstat.ips_noroute++; 659 goto done; 660 } 661 662 ia = ifatoia(ro.ro_rt->rt_ifa); 663 ro.ro_rt->rt_use++; 664 RTFREE(ro.ro_rt); 665 } 666 667 t = ia->ia_addr.sin_addr; 668 ip->ip_src = t; 669 ip->ip_ttl = MAXTTL; 670 671 if (optlen > 0) { 672 register u_char *cp; 673 int opt, cnt; 674 u_int len; 675 676 /* 677 * Retrieve any source routing from the incoming packet; 678 * add on any record-route or timestamp options. 679 */ 680 cp = (u_char *) (ip + 1); 681 if ((opts = ip_srcroute()) == 0 && 682 (opts = m_gethdr(M_DONTWAIT, MT_HEADER))) { 683 opts->m_len = sizeof(struct in_addr); 684 mtod(opts, struct in_addr *)->s_addr = 0; 685 } 686 if (opts) { 687 #ifdef ICMPPRINTFS 688 if (icmpprintfs) 689 printf("icmp_reflect optlen %d rt %d => ", 690 optlen, opts->m_len); 691 #endif 692 for (cnt = optlen; cnt > 0; cnt -= len, cp += len) { 693 opt = cp[IPOPT_OPTVAL]; 694 if (opt == IPOPT_EOL) 695 break; 696 if (opt == IPOPT_NOP) 697 len = 1; 698 else { 699 if (cnt < IPOPT_OLEN + sizeof(*cp)) 700 break; 701 len = cp[IPOPT_OLEN]; 702 if (len < IPOPT_OLEN + sizeof(*cp) || 703 len > cnt) 704 break; 705 } 706 /* 707 * Should check for overflow, but it "can't happen" 708 */ 709 if (opt == IPOPT_RR || opt == IPOPT_TS || 710 opt == IPOPT_SECURITY) { 711 bcopy((caddr_t)cp, 712 mtod(opts, caddr_t) + opts->m_len, len); 713 opts->m_len += len; 714 } 715 } 716 /* Terminate & pad, if necessary */ 717 if ((cnt = opts->m_len % 4) != 0) { 718 for (; cnt < 4; cnt++) { 719 *(mtod(opts, caddr_t) + opts->m_len) = 720 IPOPT_EOL; 721 opts->m_len++; 722 } 723 } 724 #ifdef ICMPPRINTFS 725 if (icmpprintfs) 726 printf("%d\n", opts->m_len); 727 #endif 728 } 729 /* 730 * Now strip out original options by copying rest of first 731 * mbuf's data back, and adjust the IP length. 732 */ 733 ip->ip_len -= optlen; 734 ip->ip_hl = sizeof(struct ip) >> 2; 735 m->m_len -= optlen; 736 if (m->m_flags & M_PKTHDR) 737 m->m_pkthdr.len -= optlen; 738 optlen += sizeof(struct ip); 739 bcopy((caddr_t)ip + optlen, (caddr_t)(ip + 1), 740 (unsigned)(m->m_len - sizeof(struct ip))); 741 } 742 m->m_flags &= ~(M_BCAST|M_MCAST); 743 icmp_send(m, opts); 744 done: 745 if (opts) 746 (void)m_free(opts); 747 } 748 749 /* 750 * Send an icmp packet back to the ip level, 751 * after supplying a checksum. 752 */ 753 void 754 icmp_send(m, opts) 755 register struct mbuf *m; 756 struct mbuf *opts; 757 { 758 register struct ip *ip = mtod(m, struct ip *); 759 register int hlen; 760 register struct icmp *icp; 761 762 hlen = ip->ip_hl << 2; 763 m->m_data += hlen; 764 m->m_len -= hlen; 765 icp = mtod(m, struct icmp *); 766 icp->icmp_cksum = 0; 767 icp->icmp_cksum = in_cksum(m, ip->ip_len - hlen); 768 m->m_data -= hlen; 769 m->m_len += hlen; 770 #ifdef ICMPPRINTFS 771 if (icmpprintfs) { 772 char buf[4 * sizeof "123"]; 773 774 strcpy(buf, inet_ntoa(ip->ip_dst)); 775 printf("icmp_send dst %s src %s\n", 776 buf, inet_ntoa(ip->ip_src)); 777 } 778 #endif 779 (void) ip_output(m, opts, NULL, 0, NULL, NULL); 780 } 781 782 n_time 783 iptime() 784 { 785 struct timeval atv; 786 u_long t; 787 788 microtime(&atv); 789 t = (atv.tv_sec % (24*60*60)) * 1000 + atv.tv_usec / 1000; 790 return (htonl(t)); 791 } 792 793 int 794 icmp_sysctl(name, namelen, oldp, oldlenp, newp, newlen) 795 int *name; 796 u_int namelen; 797 void *oldp; 798 size_t *oldlenp; 799 void *newp; 800 size_t newlen; 801 { 802 803 /* All sysctl names at this level are terminal. */ 804 if (namelen != 1) 805 return (ENOTDIR); 806 807 switch (name[0]) { 808 case ICMPCTL_MASKREPL: 809 return (sysctl_int(oldp, oldlenp, newp, newlen, &icmpmaskrepl)); 810 case ICMPCTL_BMCASTECHO: 811 return (sysctl_int(oldp, oldlenp, newp, newlen, &icmpbmcastecho)); 812 case ICMPCTL_ERRPPSLIMIT: 813 return (sysctl_int(oldp, oldlenp, newp, newlen, 814 &icmperrppslim)); 815 break; 816 case ICMPCTL_REDIRACCEPT: 817 return (sysctl_int(oldp, oldlenp, newp, newlen, 818 &icmp_rediraccept)); 819 break; 820 case ICMPCTL_REDIRTIMEOUT: { 821 int error; 822 823 error = sysctl_int(oldp, oldlenp, newp, newlen, 824 &icmp_redirtimeout); 825 if (icmp_redirect_timeout_q != NULL) { 826 if (icmp_redirtimeout == 0) { 827 rt_timer_queue_destroy(icmp_redirect_timeout_q, 828 TRUE); 829 icmp_redirect_timeout_q = NULL; 830 } else { 831 rt_timer_queue_change(icmp_redirect_timeout_q, 832 icmp_redirtimeout); 833 } 834 } else if (icmp_redirtimeout > 0) { 835 icmp_redirect_timeout_q = 836 rt_timer_queue_create(icmp_redirtimeout); 837 } 838 return (error); 839 840 break; 841 } 842 default: 843 return (ENOPROTOOPT); 844 } 845 /* NOTREACHED */ 846 } 847 848 struct rtentry * 849 icmp_mtudisc_clone(struct sockaddr *dst) 850 { 851 struct rtentry *rt; 852 int error; 853 854 rt = rtalloc1(dst, 1); 855 if (rt == 0) 856 return (NULL); 857 858 /* If we didn't get a host route, allocate one */ 859 860 if ((rt->rt_flags & RTF_HOST) == 0) { 861 struct rtentry *nrt; 862 863 error = rtrequest((int) RTM_ADD, dst, 864 (struct sockaddr *) rt->rt_gateway, 865 (struct sockaddr *) 0, 866 RTF_GATEWAY | RTF_HOST | RTF_DYNAMIC, &nrt); 867 if (error) { 868 rtfree(rt); 869 return (NULL); 870 } 871 nrt->rt_rmx = rt->rt_rmx; 872 rtfree(rt); 873 rt = nrt; 874 } 875 error = rt_timer_add(rt, icmp_mtudisc_timeout, ip_mtudisc_timeout_q); 876 if (error) { 877 rtfree(rt); 878 return (NULL); 879 } 880 881 return (rt); 882 } 883 884 void 885 icmp_mtudisc(icp) 886 struct icmp *icp; 887 { 888 struct rtentry *rt; 889 struct sockaddr *dst = sintosa(&icmpsrc); 890 u_long mtu = ntohs(icp->icmp_nextmtu); /* Why a long? IPv6 */ 891 892 /* Table of common MTUs: */ 893 894 static u_short mtu_table[] = {65535, 65280, 32000, 17914, 9180, 8166, 895 4352, 2002, 1492, 1006, 508, 296, 68, 0}; 896 897 rt = icmp_mtudisc_clone(dst); 898 if (rt == 0) 899 return; 900 901 if (mtu == 0) { 902 int i = 0; 903 904 mtu = icp->icmp_ip.ip_len; /* NTOHS happened in deliver: */ 905 /* Some 4.2BSD-based routers incorrectly adjust the ip_len */ 906 if (mtu > rt->rt_rmx.rmx_mtu && rt->rt_rmx.rmx_mtu != 0) 907 mtu -= (icp->icmp_ip.ip_hl << 2); 908 909 /* If we still can't guess a value, try the route */ 910 911 if (mtu == 0) { 912 mtu = rt->rt_rmx.rmx_mtu; 913 914 /* If no route mtu, default to the interface mtu */ 915 916 if (mtu == 0) 917 mtu = rt->rt_ifp->if_mtu; 918 } 919 920 for (i = 0; i < sizeof(mtu_table) / sizeof(mtu_table[0]); i++) 921 if (mtu > mtu_table[i]) { 922 mtu = mtu_table[i]; 923 break; 924 } 925 } 926 927 /* 928 * XXX: RTV_MTU is overloaded, since the admin can set it 929 * to turn off PMTU for a route, and the kernel can 930 * set it to indicate a serious problem with PMTU 931 * on a route. We should be using a separate flag 932 * for the kernel to indicate this. 933 */ 934 935 if ((rt->rt_rmx.rmx_locks & RTV_MTU) == 0) { 936 if (mtu < 296 || mtu > rt->rt_ifp->if_mtu) 937 rt->rt_rmx.rmx_locks |= RTV_MTU; 938 else if (rt->rt_rmx.rmx_mtu > mtu || 939 rt->rt_rmx.rmx_mtu == 0) 940 rt->rt_rmx.rmx_mtu = mtu; 941 } 942 943 rtfree(rt); 944 } 945 946 void 947 icmp_mtudisc_timeout(rt, r) 948 struct rtentry *rt; 949 struct rttimer *r; 950 { 951 if (rt == NULL) 952 panic("icmp_mtudisc_timeout: bad route to timeout"); 953 if ((rt->rt_flags & (RTF_DYNAMIC | RTF_HOST)) == 954 (RTF_DYNAMIC | RTF_HOST)) { 955 void *(*ctlfunc) __P((int, struct sockaddr *, void *)); 956 extern u_char ip_protox[]; 957 struct sockaddr_in sa; 958 959 sa = *(struct sockaddr_in *)rt_key(rt); 960 rtrequest((int) RTM_DELETE, (struct sockaddr *)rt_key(rt), 961 rt->rt_gateway, rt_mask(rt), rt->rt_flags, 0); 962 963 /* Notify TCP layer of increased Path MTU estimate */ 964 ctlfunc = inetsw[ip_protox[IPPROTO_TCP]].pr_ctlinput; 965 if (ctlfunc) 966 (*ctlfunc)(PRC_MTUINC,(struct sockaddr *)&sa, NULL); 967 } else { 968 if ((rt->rt_rmx.rmx_locks & RTV_MTU) == 0) { 969 rt->rt_rmx.rmx_mtu = 0; 970 } 971 } 972 } 973 974 /* 975 * Perform rate limit check. 976 * Returns 0 if it is okay to send the icmp packet. 977 * Returns 1 if the router SHOULD NOT send this icmp packet due to rate 978 * limitation. 979 * 980 * XXX per-destination/type check necessary? 981 */ 982 int 983 icmp_ratelimit(dst, type, code) 984 const struct in_addr *dst; 985 const int type; /* not used at this moment */ 986 const int code; /* not used at this moment */ 987 { 988 989 /* PPS limit */ 990 if (!ppsratecheck(&icmperrppslim_last, &icmperrpps_count, 991 icmperrppslim)) { 992 /* The packet is subject to rate limit */ 993 return 1; 994 } 995 996 /*okay to send*/ 997 return 0; 998 } 999 1000 static void 1001 icmp_redirect_timeout(rt, r) 1002 struct rtentry *rt; 1003 struct rttimer *r; 1004 { 1005 if (rt == NULL) 1006 panic("icmp_redirect_timeout: bad route to timeout"); 1007 if ((rt->rt_flags & (RTF_DYNAMIC | RTF_HOST)) == 1008 (RTF_DYNAMIC | RTF_HOST)) { 1009 rtrequest((int) RTM_DELETE, (struct sockaddr *)rt_key(rt), 1010 rt->rt_gateway, rt_mask(rt), rt->rt_flags, 0); 1011 } 1012 } 1013