1 /* 2 * Copyright (c) 1982, 1986, 1988, 1993 3 * The Regents of the University of California. All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 1. Redistributions of source code must retain the above copyright 9 * notice, this list of conditions and the following disclaimer. 10 * 2. Redistributions in binary form must reproduce the above copyright 11 * notice, this list of conditions and the following disclaimer in the 12 * documentation and/or other materials provided with the distribution. 13 * 3. All advertising materials mentioning features or use of this software 14 * must display the following acknowledgement: 15 * This product includes software developed by the University of 16 * California, Berkeley and its contributors. 17 * 4. Neither the name of the University nor the names of its contributors 18 * may be used to endorse or promote products derived from this software 19 * without specific prior written permission. 20 * 21 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 22 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 23 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 24 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 25 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 26 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 27 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 28 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 29 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 30 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 31 * SUCH DAMAGE. 32 * 33 * @(#)ip_icmp.c 8.2 (Berkeley) 1/4/94 34 * $FreeBSD$ 35 */ 36 37 #include "opt_ipsec.h" 38 39 #include <sys/param.h> 40 #include <sys/systm.h> 41 #include <sys/mbuf.h> 42 #include <sys/protosw.h> 43 #include <sys/socket.h> 44 #include <sys/time.h> 45 #include <sys/kernel.h> 46 #include <sys/sysctl.h> 47 48 #include <net/if.h> 49 #include <net/if_types.h> 50 #include <net/route.h> 51 52 #define _IP_VHL 53 #include <netinet/in.h> 54 #include <netinet/in_systm.h> 55 #include <netinet/in_var.h> 56 #include <netinet/ip.h> 57 #include <netinet/ip_icmp.h> 58 #include <netinet/ip_var.h> 59 #include <netinet/icmp_var.h> 60 61 #ifdef IPSEC 62 #include <netinet6/ipsec.h> 63 #include <netkey/key.h> 64 #endif 65 66 #include <machine/in_cksum.h> 67 68 /* 69 * ICMP routines: error generation, receive packet processing, and 70 * routines to turnaround packets back to the originator, and 71 * host table maintenance routines. 72 */ 73 74 static struct icmpstat icmpstat; 75 SYSCTL_STRUCT(_net_inet_icmp, ICMPCTL_STATS, stats, CTLFLAG_RW, 76 &icmpstat, icmpstat, ""); 77 78 static int icmpmaskrepl = 0; 79 SYSCTL_INT(_net_inet_icmp, ICMPCTL_MASKREPL, maskrepl, CTLFLAG_RW, 80 &icmpmaskrepl, 0, ""); 81 82 static int drop_redirect = 0; 83 SYSCTL_INT(_net_inet_icmp, OID_AUTO, drop_redirect, CTLFLAG_RW, 84 &drop_redirect, 0, ""); 85 86 static int log_redirect = 0; 87 SYSCTL_INT(_net_inet_icmp, OID_AUTO, log_redirect, CTLFLAG_RW, 88 &log_redirect, 0, ""); 89 90 static int icmplim = 200; 91 SYSCTL_INT(_net_inet_icmp, ICMPCTL_ICMPLIM, icmplim, CTLFLAG_RW, 92 &icmplim, 0, ""); 93 94 static int icmplim_output = 1; 95 SYSCTL_INT(_net_inet_icmp, OID_AUTO, icmplim_output, CTLFLAG_RW, 96 &icmplim_output, 0, ""); 97 98 /* 99 * ICMP broadcast echo sysctl 100 */ 101 102 static int icmpbmcastecho = 0; 103 SYSCTL_INT(_net_inet_icmp, OID_AUTO, bmcastecho, CTLFLAG_RW, 104 &icmpbmcastecho, 0, ""); 105 106 107 #ifdef ICMPPRINTFS 108 int icmpprintfs = 0; 109 #endif 110 111 static void icmp_reflect(struct mbuf *); 112 static void icmp_send(struct mbuf *, struct mbuf *, struct route *); 113 static int ip_next_mtu(int, int); 114 115 extern struct protosw inetsw[]; 116 117 /* 118 * Generate an error packet of type error 119 * in response to bad packet ip. 120 */ 121 void 122 icmp_error(n, type, code, dest, destifp) 123 struct mbuf *n; 124 int type, code; 125 n_long dest; 126 struct ifnet *destifp; 127 { 128 register struct ip *oip = mtod(n, struct ip *), *nip; 129 register unsigned oiplen = IP_VHL_HL(oip->ip_vhl) << 2; 130 register struct icmp *icp; 131 register struct mbuf *m; 132 unsigned icmplen; 133 134 #ifdef ICMPPRINTFS 135 if (icmpprintfs) 136 printf("icmp_error(%p, %x, %d)\n", oip, type, code); 137 #endif 138 if (type != ICMP_REDIRECT) 139 icmpstat.icps_error++; 140 /* 141 * Don't send error if not the first fragment of message. 142 * Don't error if the old packet protocol was ICMP 143 * error message, only known informational types. 144 */ 145 if (oip->ip_off &~ (IP_MF|IP_DF)) 146 goto freeit; 147 if (oip->ip_p == IPPROTO_ICMP && type != ICMP_REDIRECT && 148 n->m_len >= oiplen + ICMP_MINLEN && 149 !ICMP_INFOTYPE(((struct icmp *)((caddr_t)oip + oiplen))->icmp_type)) { 150 icmpstat.icps_oldicmp++; 151 goto freeit; 152 } 153 /* Don't send error in response to a multicast or broadcast packet */ 154 if (n->m_flags & (M_BCAST|M_MCAST)) 155 goto freeit; 156 /* 157 * First, formulate icmp message 158 */ 159 m = m_gethdr(M_DONTWAIT, MT_HEADER); 160 if (m == NULL) 161 goto freeit; 162 icmplen = min(oiplen + 8, oip->ip_len); 163 if (icmplen < sizeof(struct ip)) 164 panic("icmp_error: bad length"); 165 m->m_len = icmplen + ICMP_MINLEN; 166 MH_ALIGN(m, m->m_len); 167 icp = mtod(m, struct icmp *); 168 if ((u_int)type > ICMP_MAXTYPE) 169 panic("icmp_error"); 170 icmpstat.icps_outhist[type]++; 171 icp->icmp_type = type; 172 if (type == ICMP_REDIRECT) 173 icp->icmp_gwaddr.s_addr = dest; 174 else { 175 icp->icmp_void = 0; 176 /* 177 * The following assignments assume an overlay with the 178 * zeroed icmp_void field. 179 */ 180 if (type == ICMP_PARAMPROB) { 181 icp->icmp_pptr = code; 182 code = 0; 183 } else if (type == ICMP_UNREACH && 184 code == ICMP_UNREACH_NEEDFRAG && destifp) { 185 icp->icmp_nextmtu = htons(destifp->if_mtu); 186 } 187 } 188 189 icp->icmp_code = code; 190 m_copydata(n, 0, icmplen, (caddr_t)&icp->icmp_ip); 191 nip = &icp->icmp_ip; 192 193 /* 194 * Convert fields to network representation. 195 */ 196 nip->ip_len = htons(nip->ip_len); 197 nip->ip_off = htons(nip->ip_off); 198 199 /* 200 * Now, copy old ip header (without options) 201 * in front of icmp message. 202 */ 203 if (m->m_data - sizeof(struct ip) < m->m_pktdat) 204 panic("icmp len"); 205 m->m_data -= sizeof(struct ip); 206 m->m_len += sizeof(struct ip); 207 m->m_pkthdr.len = m->m_len; 208 m->m_pkthdr.rcvif = n->m_pkthdr.rcvif; 209 nip = mtod(m, struct ip *); 210 bcopy((caddr_t)oip, (caddr_t)nip, sizeof(struct ip)); 211 nip->ip_len = m->m_len; 212 nip->ip_vhl = IP_VHL_BORING; 213 nip->ip_p = IPPROTO_ICMP; 214 nip->ip_tos = 0; 215 icmp_reflect(m); 216 217 freeit: 218 m_freem(n); 219 } 220 221 static struct sockaddr_in icmpsrc = { sizeof (struct sockaddr_in), AF_INET }; 222 static struct sockaddr_in icmpdst = { sizeof (struct sockaddr_in), AF_INET }; 223 static struct sockaddr_in icmpgw = { sizeof (struct sockaddr_in), AF_INET }; 224 225 /* 226 * Process a received ICMP message. 227 */ 228 void 229 icmp_input(m, off) 230 register struct mbuf *m; 231 int off; 232 { 233 int hlen = off; 234 register struct icmp *icp; 235 register struct ip *ip = mtod(m, struct ip *); 236 int icmplen = ip->ip_len; 237 register int i; 238 struct in_ifaddr *ia; 239 void (*ctlfunc)(int, struct sockaddr *, void *); 240 int code; 241 242 /* 243 * Locate icmp structure in mbuf, and check 244 * that not corrupted and of at least minimum length. 245 */ 246 #ifdef ICMPPRINTFS 247 if (icmpprintfs) { 248 char buf[4 * sizeof "123"]; 249 strcpy(buf, inet_ntoa(ip->ip_src)); 250 printf("icmp_input from %s to %s, len %d\n", 251 buf, inet_ntoa(ip->ip_dst), icmplen); 252 } 253 #endif 254 if (icmplen < ICMP_MINLEN) { 255 icmpstat.icps_tooshort++; 256 goto freeit; 257 } 258 i = hlen + min(icmplen, ICMP_ADVLENMIN); 259 if (m->m_len < i && (m = m_pullup(m, i)) == 0) { 260 icmpstat.icps_tooshort++; 261 return; 262 } 263 ip = mtod(m, struct ip *); 264 m->m_len -= hlen; 265 m->m_data += hlen; 266 icp = mtod(m, struct icmp *); 267 if (in_cksum(m, icmplen)) { 268 icmpstat.icps_checksum++; 269 goto freeit; 270 } 271 m->m_len += hlen; 272 m->m_data -= hlen; 273 274 if (m->m_pkthdr.rcvif && m->m_pkthdr.rcvif->if_type == IFT_FAITH) { 275 /* 276 * Deliver very specific ICMP type only. 277 */ 278 switch (icp->icmp_type) { 279 case ICMP_UNREACH: 280 case ICMP_TIMXCEED: 281 break; 282 default: 283 goto freeit; 284 } 285 } 286 287 #ifdef ICMPPRINTFS 288 if (icmpprintfs) 289 printf("icmp_input, type %d code %d\n", icp->icmp_type, 290 icp->icmp_code); 291 #endif 292 293 /* 294 * Message type specific processing. 295 */ 296 if (icp->icmp_type > ICMP_MAXTYPE) 297 goto raw; 298 icmpstat.icps_inhist[icp->icmp_type]++; 299 code = icp->icmp_code; 300 switch (icp->icmp_type) { 301 302 case ICMP_UNREACH: 303 switch (code) { 304 case ICMP_UNREACH_NET: 305 case ICMP_UNREACH_HOST: 306 case ICMP_UNREACH_SRCFAIL: 307 case ICMP_UNREACH_NET_UNKNOWN: 308 case ICMP_UNREACH_HOST_UNKNOWN: 309 case ICMP_UNREACH_ISOLATED: 310 case ICMP_UNREACH_TOSNET: 311 case ICMP_UNREACH_TOSHOST: 312 case ICMP_UNREACH_HOST_PRECEDENCE: 313 case ICMP_UNREACH_PRECEDENCE_CUTOFF: 314 code = PRC_UNREACH_NET; 315 break; 316 317 case ICMP_UNREACH_NEEDFRAG: 318 code = PRC_MSGSIZE; 319 break; 320 321 /* 322 * RFC 1122, Sections 3.2.2.1 and 4.2.3.9. 323 * Treat subcodes 2,3 as immediate RST 324 */ 325 case ICMP_UNREACH_PROTOCOL: 326 case ICMP_UNREACH_PORT: 327 code = PRC_UNREACH_PORT; 328 break; 329 330 case ICMP_UNREACH_NET_PROHIB: 331 case ICMP_UNREACH_HOST_PROHIB: 332 case ICMP_UNREACH_FILTER_PROHIB: 333 code = PRC_UNREACH_ADMIN_PROHIB; 334 break; 335 336 default: 337 goto badcode; 338 } 339 goto deliver; 340 341 case ICMP_TIMXCEED: 342 if (code > 1) 343 goto badcode; 344 code += PRC_TIMXCEED_INTRANS; 345 goto deliver; 346 347 case ICMP_PARAMPROB: 348 if (code > 1) 349 goto badcode; 350 code = PRC_PARAMPROB; 351 goto deliver; 352 353 case ICMP_SOURCEQUENCH: 354 if (code) 355 goto badcode; 356 code = PRC_QUENCH; 357 deliver: 358 /* 359 * Problem with datagram; advise higher level routines. 360 */ 361 if (icmplen < ICMP_ADVLENMIN || icmplen < ICMP_ADVLEN(icp) || 362 IP_VHL_HL(icp->icmp_ip.ip_vhl) < (sizeof(struct ip) >> 2)) { 363 icmpstat.icps_badlen++; 364 goto freeit; 365 } 366 icp->icmp_ip.ip_len = ntohs(icp->icmp_ip.ip_len); 367 /* Discard ICMP's in response to multicast packets */ 368 if (IN_MULTICAST(ntohl(icp->icmp_ip.ip_dst.s_addr))) 369 goto badcode; 370 #ifdef ICMPPRINTFS 371 if (icmpprintfs) 372 printf("deliver to protocol %d\n", icp->icmp_ip.ip_p); 373 #endif 374 icmpsrc.sin_addr = icp->icmp_ip.ip_dst; 375 #if 1 376 /* 377 * MTU discovery: 378 * If we got a needfrag and there is a host route to the 379 * original destination, and the MTU is not locked, then 380 * set the MTU in the route to the suggested new value 381 * (if given) and then notify as usual. The ULPs will 382 * notice that the MTU has changed and adapt accordingly. 383 * If no new MTU was suggested, then we guess a new one 384 * less than the current value. If the new MTU is 385 * unreasonably small (arbitrarily set at 296), then 386 * we reset the MTU to the interface value and enable the 387 * lock bit, indicating that we are no longer doing MTU 388 * discovery. 389 */ 390 if (code == PRC_MSGSIZE) { 391 struct rtentry *rt; 392 int mtu; 393 394 rt = rtalloc1((struct sockaddr *)&icmpsrc, 0, 395 RTF_CLONING | RTF_PRCLONING); 396 if (rt && (rt->rt_flags & RTF_HOST) 397 && !(rt->rt_rmx.rmx_locks & RTV_MTU)) { 398 mtu = ntohs(icp->icmp_nextmtu); 399 if (!mtu) 400 mtu = ip_next_mtu(rt->rt_rmx.rmx_mtu, 401 1); 402 #ifdef DEBUG_MTUDISC 403 printf("MTU for %s reduced to %d\n", 404 inet_ntoa(icmpsrc.sin_addr), mtu); 405 #endif 406 if (mtu < 296) { 407 /* rt->rt_rmx.rmx_mtu = 408 rt->rt_ifp->if_mtu; */ 409 rt->rt_rmx.rmx_locks |= RTV_MTU; 410 } else if (rt->rt_rmx.rmx_mtu > mtu) { 411 rt->rt_rmx.rmx_mtu = mtu; 412 } 413 } 414 if (rt) 415 RTFREE(rt); 416 } 417 418 #endif 419 /* 420 * XXX if the packet contains [IPv4 AH TCP], we can't make a 421 * notification to TCP layer. 422 */ 423 ctlfunc = inetsw[ip_protox[icp->icmp_ip.ip_p]].pr_ctlinput; 424 if (ctlfunc) 425 (*ctlfunc)(code, (struct sockaddr *)&icmpsrc, 426 (void *)&icp->icmp_ip); 427 break; 428 429 badcode: 430 icmpstat.icps_badcode++; 431 break; 432 433 case ICMP_ECHO: 434 if (!icmpbmcastecho 435 && (m->m_flags & (M_MCAST | M_BCAST)) != 0) { 436 icmpstat.icps_bmcastecho++; 437 break; 438 } 439 icp->icmp_type = ICMP_ECHOREPLY; 440 if (badport_bandlim(BANDLIM_ICMP_ECHO) < 0) 441 goto freeit; 442 else 443 goto reflect; 444 445 case ICMP_TSTAMP: 446 if (!icmpbmcastecho 447 && (m->m_flags & (M_MCAST | M_BCAST)) != 0) { 448 icmpstat.icps_bmcasttstamp++; 449 break; 450 } 451 if (icmplen < ICMP_TSLEN) { 452 icmpstat.icps_badlen++; 453 break; 454 } 455 icp->icmp_type = ICMP_TSTAMPREPLY; 456 icp->icmp_rtime = iptime(); 457 icp->icmp_ttime = icp->icmp_rtime; /* bogus, do later! */ 458 if (badport_bandlim(BANDLIM_ICMP_TSTAMP) < 0) 459 goto freeit; 460 else 461 goto reflect; 462 463 case ICMP_MASKREQ: 464 if (icmpmaskrepl == 0) 465 break; 466 /* 467 * We are not able to respond with all ones broadcast 468 * unless we receive it over a point-to-point interface. 469 */ 470 if (icmplen < ICMP_MASKLEN) 471 break; 472 switch (ip->ip_dst.s_addr) { 473 474 case INADDR_BROADCAST: 475 case INADDR_ANY: 476 icmpdst.sin_addr = ip->ip_src; 477 break; 478 479 default: 480 icmpdst.sin_addr = ip->ip_dst; 481 } 482 ia = (struct in_ifaddr *)ifaof_ifpforaddr( 483 (struct sockaddr *)&icmpdst, m->m_pkthdr.rcvif); 484 if (ia == 0) 485 break; 486 if (ia->ia_ifp == 0) 487 break; 488 icp->icmp_type = ICMP_MASKREPLY; 489 icp->icmp_mask = ia->ia_sockmask.sin_addr.s_addr; 490 if (ip->ip_src.s_addr == 0) { 491 if (ia->ia_ifp->if_flags & IFF_BROADCAST) 492 ip->ip_src = satosin(&ia->ia_broadaddr)->sin_addr; 493 else if (ia->ia_ifp->if_flags & IFF_POINTOPOINT) 494 ip->ip_src = satosin(&ia->ia_dstaddr)->sin_addr; 495 } 496 reflect: 497 ip->ip_len += hlen; /* since ip_input deducts this */ 498 icmpstat.icps_reflect++; 499 icmpstat.icps_outhist[icp->icmp_type]++; 500 icmp_reflect(m); 501 return; 502 503 case ICMP_REDIRECT: 504 if (log_redirect) { 505 u_long src, dst, gw; 506 507 src = ntohl(ip->ip_src.s_addr); 508 dst = ntohl(icp->icmp_ip.ip_dst.s_addr); 509 gw = ntohl(icp->icmp_gwaddr.s_addr); 510 printf("icmp redirect from %d.%d.%d.%d: " 511 "%d.%d.%d.%d => %d.%d.%d.%d\n", 512 (int)(src >> 24), (int)((src >> 16) & 0xff), 513 (int)((src >> 8) & 0xff), (int)(src & 0xff), 514 (int)(dst >> 24), (int)((dst >> 16) & 0xff), 515 (int)((dst >> 8) & 0xff), (int)(dst & 0xff), 516 (int)(gw >> 24), (int)((gw >> 16) & 0xff), 517 (int)((gw >> 8) & 0xff), (int)(gw & 0xff)); 518 } 519 if (drop_redirect) 520 break; 521 if (code > 3) 522 goto badcode; 523 if (icmplen < ICMP_ADVLENMIN || icmplen < ICMP_ADVLEN(icp) || 524 IP_VHL_HL(icp->icmp_ip.ip_vhl) < (sizeof(struct ip) >> 2)) { 525 icmpstat.icps_badlen++; 526 break; 527 } 528 /* 529 * Short circuit routing redirects to force 530 * immediate change in the kernel's routing 531 * tables. The message is also handed to anyone 532 * listening on a raw socket (e.g. the routing 533 * daemon for use in updating its tables). 534 */ 535 icmpgw.sin_addr = ip->ip_src; 536 icmpdst.sin_addr = icp->icmp_gwaddr; 537 #ifdef ICMPPRINTFS 538 if (icmpprintfs) { 539 char buf[4 * sizeof "123"]; 540 strcpy(buf, inet_ntoa(icp->icmp_ip.ip_dst)); 541 542 printf("redirect dst %s to %s\n", 543 buf, inet_ntoa(icp->icmp_gwaddr)); 544 } 545 #endif 546 icmpsrc.sin_addr = icp->icmp_ip.ip_dst; 547 rtredirect((struct sockaddr *)&icmpsrc, 548 (struct sockaddr *)&icmpdst, 549 (struct sockaddr *)0, RTF_GATEWAY | RTF_HOST, 550 (struct sockaddr *)&icmpgw, (struct rtentry **)0); 551 pfctlinput(PRC_REDIRECT_HOST, (struct sockaddr *)&icmpsrc); 552 #ifdef IPSEC 553 key_sa_routechange((struct sockaddr *)&icmpsrc); 554 #endif 555 break; 556 557 /* 558 * No kernel processing for the following; 559 * just fall through to send to raw listener. 560 */ 561 case ICMP_ECHOREPLY: 562 case ICMP_ROUTERADVERT: 563 case ICMP_ROUTERSOLICIT: 564 case ICMP_TSTAMPREPLY: 565 case ICMP_IREQREPLY: 566 case ICMP_MASKREPLY: 567 default: 568 break; 569 } 570 571 raw: 572 rip_input(m, off); 573 return; 574 575 freeit: 576 m_freem(m); 577 } 578 579 /* 580 * Reflect the ip packet back to the source 581 */ 582 static void 583 icmp_reflect(m) 584 struct mbuf *m; 585 { 586 struct ip *ip = mtod(m, struct ip *); 587 struct ifaddr *ifa; 588 struct in_ifaddr *ia; 589 struct in_addr t; 590 struct mbuf *opts = 0; 591 int optlen = (IP_VHL_HL(ip->ip_vhl) << 2) - sizeof(struct ip); 592 struct route *ro = NULL, rt; 593 594 if (!in_canforward(ip->ip_src) && 595 ((ntohl(ip->ip_src.s_addr) & IN_CLASSA_NET) != 596 (IN_LOOPBACKNET << IN_CLASSA_NSHIFT))) { 597 m_freem(m); /* Bad return address */ 598 icmpstat.icps_badaddr++; 599 goto done; /* Ip_output() will check for broadcast */ 600 } 601 t = ip->ip_dst; 602 ip->ip_dst = ip->ip_src; 603 ro = &rt; 604 bzero(ro, sizeof(*ro)); 605 /* 606 * If the incoming packet was addressed directly to us, 607 * use dst as the src for the reply. Otherwise (broadcast 608 * or anonymous), use the address which corresponds 609 * to the incoming interface. 610 */ 611 LIST_FOREACH(ia, INADDR_HASH(t.s_addr), ia_hash) 612 if (t.s_addr == IA_SIN(ia)->sin_addr.s_addr) 613 goto match; 614 if (m->m_pkthdr.rcvif != NULL && 615 m->m_pkthdr.rcvif->if_flags & IFF_BROADCAST) { 616 TAILQ_FOREACH(ifa, &m->m_pkthdr.rcvif->if_addrhead, ifa_link) { 617 if (ifa->ifa_addr->sa_family != AF_INET) 618 continue; 619 ia = ifatoia(ifa); 620 if (satosin(&ia->ia_broadaddr)->sin_addr.s_addr == 621 t.s_addr) 622 goto match; 623 } 624 } 625 ia = ip_rtaddr(ip->ip_dst, ro); 626 /* We need a route to do anything useful. */ 627 if (ia == NULL) { 628 m_freem(m); 629 icmpstat.icps_noroute++; 630 goto done; 631 } 632 match: 633 t = IA_SIN(ia)->sin_addr; 634 ip->ip_src = t; 635 ip->ip_ttl = ip_defttl; 636 637 if (optlen > 0) { 638 register u_char *cp; 639 int opt, cnt; 640 u_int len; 641 642 /* 643 * Retrieve any source routing from the incoming packet; 644 * add on any record-route or timestamp options. 645 */ 646 cp = (u_char *) (ip + 1); 647 if ((opts = ip_srcroute()) == 0 && 648 (opts = m_gethdr(M_DONTWAIT, MT_HEADER))) { 649 opts->m_len = sizeof(struct in_addr); 650 mtod(opts, struct in_addr *)->s_addr = 0; 651 } 652 if (opts) { 653 #ifdef ICMPPRINTFS 654 if (icmpprintfs) 655 printf("icmp_reflect optlen %d rt %d => ", 656 optlen, opts->m_len); 657 #endif 658 for (cnt = optlen; cnt > 0; cnt -= len, cp += len) { 659 opt = cp[IPOPT_OPTVAL]; 660 if (opt == IPOPT_EOL) 661 break; 662 if (opt == IPOPT_NOP) 663 len = 1; 664 else { 665 if (cnt < IPOPT_OLEN + sizeof(*cp)) 666 break; 667 len = cp[IPOPT_OLEN]; 668 if (len < IPOPT_OLEN + sizeof(*cp) || 669 len > cnt) 670 break; 671 } 672 /* 673 * Should check for overflow, but it "can't happen" 674 */ 675 if (opt == IPOPT_RR || opt == IPOPT_TS || 676 opt == IPOPT_SECURITY) { 677 bcopy((caddr_t)cp, 678 mtod(opts, caddr_t) + opts->m_len, len); 679 opts->m_len += len; 680 } 681 } 682 /* Terminate & pad, if necessary */ 683 cnt = opts->m_len % 4; 684 if (cnt) { 685 for (; cnt < 4; cnt++) { 686 *(mtod(opts, caddr_t) + opts->m_len) = 687 IPOPT_EOL; 688 opts->m_len++; 689 } 690 } 691 #ifdef ICMPPRINTFS 692 if (icmpprintfs) 693 printf("%d\n", opts->m_len); 694 #endif 695 } 696 /* 697 * Now strip out original options by copying rest of first 698 * mbuf's data back, and adjust the IP length. 699 */ 700 ip->ip_len -= optlen; 701 ip->ip_vhl = IP_VHL_BORING; 702 m->m_len -= optlen; 703 if (m->m_flags & M_PKTHDR) 704 m->m_pkthdr.len -= optlen; 705 optlen += sizeof(struct ip); 706 bcopy((caddr_t)ip + optlen, (caddr_t)(ip + 1), 707 (unsigned)(m->m_len - sizeof(struct ip))); 708 } 709 m->m_flags &= ~(M_BCAST|M_MCAST); 710 icmp_send(m, opts, ro); 711 done: 712 if (opts) 713 (void)m_free(opts); 714 if (ro && ro->ro_rt) 715 RTFREE(ro->ro_rt); 716 } 717 718 /* 719 * Send an icmp packet back to the ip level, 720 * after supplying a checksum. 721 */ 722 static void 723 icmp_send(m, opts, rt) 724 register struct mbuf *m; 725 struct mbuf *opts; 726 struct route *rt; 727 { 728 register struct ip *ip = mtod(m, struct ip *); 729 register int hlen; 730 register struct icmp *icp; 731 732 hlen = IP_VHL_HL(ip->ip_vhl) << 2; 733 m->m_data += hlen; 734 m->m_len -= hlen; 735 icp = mtod(m, struct icmp *); 736 icp->icmp_cksum = 0; 737 icp->icmp_cksum = in_cksum(m, ip->ip_len - hlen); 738 m->m_data -= hlen; 739 m->m_len += hlen; 740 m->m_pkthdr.rcvif = (struct ifnet *)0; 741 #ifdef ICMPPRINTFS 742 if (icmpprintfs) { 743 char buf[4 * sizeof "123"]; 744 strcpy(buf, inet_ntoa(ip->ip_dst)); 745 printf("icmp_send dst %s src %s\n", 746 buf, inet_ntoa(ip->ip_src)); 747 } 748 #endif 749 (void) ip_output(m, opts, rt, 0, NULL); 750 } 751 752 n_time 753 iptime() 754 { 755 struct timeval atv; 756 u_long t; 757 758 getmicrotime(&atv); 759 t = (atv.tv_sec % (24*60*60)) * 1000 + atv.tv_usec / 1000; 760 return (htonl(t)); 761 } 762 763 #if 1 764 /* 765 * Return the next larger or smaller MTU plateau (table from RFC 1191) 766 * given current value MTU. If DIR is less than zero, a larger plateau 767 * is returned; otherwise, a smaller value is returned. 768 */ 769 static int 770 ip_next_mtu(mtu, dir) 771 int mtu; 772 int dir; 773 { 774 static int mtutab[] = { 775 65535, 32000, 17914, 8166, 4352, 2002, 1492, 1006, 508, 296, 776 68, 0 777 }; 778 int i; 779 780 for (i = 0; i < (sizeof mtutab) / (sizeof mtutab[0]); i++) { 781 if (mtu >= mtutab[i]) 782 break; 783 } 784 785 if (dir < 0) { 786 if (i == 0) { 787 return 0; 788 } else { 789 return mtutab[i - 1]; 790 } 791 } else { 792 if (mtutab[i] == 0) { 793 return 0; 794 } else if(mtu > mtutab[i]) { 795 return mtutab[i]; 796 } else { 797 return mtutab[i + 1]; 798 } 799 } 800 } 801 #endif 802 803 804 /* 805 * badport_bandlim() - check for ICMP bandwidth limit 806 * 807 * Return 0 if it is ok to send an ICMP error response, -1 if we have 808 * hit our bandwidth limit and it is not ok. 809 * 810 * If icmplim is <= 0, the feature is disabled and 0 is returned. 811 * 812 * For now we separate the TCP and UDP subsystems w/ different 'which' 813 * values. We may eventually remove this separation (and simplify the 814 * code further). 815 * 816 * Note that the printing of the error message is delayed so we can 817 * properly print the icmp error rate that the system was trying to do 818 * (i.e. 22000/100 pps, etc...). This can cause long delays in printing 819 * the 'final' error, but it doesn't make sense to solve the printing 820 * delay with more complex code. 821 */ 822 823 int 824 badport_bandlim(int which) 825 { 826 static int lticks[BANDLIM_MAX + 1]; 827 static int lpackets[BANDLIM_MAX + 1]; 828 int dticks; 829 const char *bandlimittype[] = { 830 "Limiting icmp unreach response", 831 "Limiting icmp ping response", 832 "Limiting icmp tstamp response", 833 "Limiting closed port RST response", 834 "Limiting open port RST response" 835 }; 836 837 /* 838 * Return ok status if feature disabled or argument out of 839 * ranage. 840 */ 841 842 if (icmplim <= 0 || which > BANDLIM_MAX || which < 0) 843 return(0); 844 dticks = ticks - lticks[which]; 845 846 /* 847 * reset stats when cumulative dt exceeds one second. 848 */ 849 850 if ((unsigned int)dticks > hz) { 851 if (lpackets[which] > icmplim && icmplim_output) { 852 printf("%s from %d to %d packets per second\n", 853 bandlimittype[which], 854 lpackets[which], 855 icmplim 856 ); 857 } 858 lticks[which] = ticks; 859 lpackets[which] = 0; 860 } 861 862 /* 863 * bump packet count 864 */ 865 866 if (++lpackets[which] > icmplim) { 867 return(-1); 868 } 869 return(0); 870 } 871 872