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 __P((struct mbuf *)); 112 static void icmp_send __P((struct mbuf *, struct mbuf *)); 113 static int ip_next_mtu __P((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 HTONS(nip->ip_len); 197 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) __P((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 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 593 if (!in_canforward(ip->ip_src) && 594 ((ntohl(ip->ip_src.s_addr) & IN_CLASSA_NET) != 595 (IN_LOOPBACKNET << IN_CLASSA_NSHIFT))) { 596 m_freem(m); /* Bad return address */ 597 goto done; /* Ip_output() will check for broadcast */ 598 } 599 t = ip->ip_dst; 600 ip->ip_dst = ip->ip_src; 601 /* 602 * If the incoming packet was addressed directly to us, 603 * use dst as the src for the reply. Otherwise (broadcast 604 * or anonymous), use the address which corresponds 605 * to the incoming interface. 606 */ 607 LIST_FOREACH(ia, INADDR_HASH(t.s_addr), ia_hash) 608 if (t.s_addr == IA_SIN(ia)->sin_addr.s_addr) 609 goto match; 610 KASSERT(m->m_pkthdr.rcvif != NULL, ("icmp_reflect: NULL rcvif")); 611 if (m->m_pkthdr.rcvif->if_flags & IFF_BROADCAST) { 612 TAILQ_FOREACH(ifa, &m->m_pkthdr.rcvif->if_addrhead, ifa_link) { 613 if (ifa->ifa_addr->sa_family != AF_INET) 614 continue; 615 ia = ifatoia(ifa); 616 if (satosin(&ia->ia_broadaddr)->sin_addr.s_addr == 617 t.s_addr) 618 goto match; 619 } 620 } 621 icmpdst.sin_addr = t; 622 ia = (struct in_ifaddr *)ifaof_ifpforaddr( 623 (struct sockaddr *)&icmpdst, m->m_pkthdr.rcvif); 624 /* 625 * The following happens if the packet was not addressed to us, 626 * and was received on an interface with no IP address. 627 */ 628 if (ia == NULL) 629 ia = TAILQ_FIRST(&in_ifaddrhead); 630 match: 631 t = IA_SIN(ia)->sin_addr; 632 ip->ip_src = t; 633 ip->ip_ttl = ip_defttl; 634 635 if (optlen > 0) { 636 register u_char *cp; 637 int opt, cnt; 638 u_int len; 639 640 /* 641 * Retrieve any source routing from the incoming packet; 642 * add on any record-route or timestamp options. 643 */ 644 cp = (u_char *) (ip + 1); 645 if ((opts = ip_srcroute()) == 0 && 646 (opts = m_gethdr(M_DONTWAIT, MT_HEADER))) { 647 opts->m_len = sizeof(struct in_addr); 648 mtod(opts, struct in_addr *)->s_addr = 0; 649 } 650 if (opts) { 651 #ifdef ICMPPRINTFS 652 if (icmpprintfs) 653 printf("icmp_reflect optlen %d rt %d => ", 654 optlen, opts->m_len); 655 #endif 656 for (cnt = optlen; cnt > 0; cnt -= len, cp += len) { 657 opt = cp[IPOPT_OPTVAL]; 658 if (opt == IPOPT_EOL) 659 break; 660 if (opt == IPOPT_NOP) 661 len = 1; 662 else { 663 if (cnt < IPOPT_OLEN + sizeof(*cp)) 664 break; 665 len = cp[IPOPT_OLEN]; 666 if (len < IPOPT_OLEN + sizeof(*cp) || 667 len > cnt) 668 break; 669 } 670 /* 671 * Should check for overflow, but it "can't happen" 672 */ 673 if (opt == IPOPT_RR || opt == IPOPT_TS || 674 opt == IPOPT_SECURITY) { 675 bcopy((caddr_t)cp, 676 mtod(opts, caddr_t) + opts->m_len, len); 677 opts->m_len += len; 678 } 679 } 680 /* Terminate & pad, if necessary */ 681 cnt = opts->m_len % 4; 682 if (cnt) { 683 for (; cnt < 4; cnt++) { 684 *(mtod(opts, caddr_t) + opts->m_len) = 685 IPOPT_EOL; 686 opts->m_len++; 687 } 688 } 689 #ifdef ICMPPRINTFS 690 if (icmpprintfs) 691 printf("%d\n", opts->m_len); 692 #endif 693 } 694 /* 695 * Now strip out original options by copying rest of first 696 * mbuf's data back, and adjust the IP length. 697 */ 698 ip->ip_len -= optlen; 699 ip->ip_vhl = IP_VHL_BORING; 700 m->m_len -= optlen; 701 if (m->m_flags & M_PKTHDR) 702 m->m_pkthdr.len -= optlen; 703 optlen += sizeof(struct ip); 704 bcopy((caddr_t)ip + optlen, (caddr_t)(ip + 1), 705 (unsigned)(m->m_len - sizeof(struct ip))); 706 } 707 m->m_flags &= ~(M_BCAST|M_MCAST); 708 icmp_send(m, opts); 709 done: 710 if (opts) 711 (void)m_free(opts); 712 } 713 714 /* 715 * Send an icmp packet back to the ip level, 716 * after supplying a checksum. 717 */ 718 static void 719 icmp_send(m, opts) 720 register struct mbuf *m; 721 struct mbuf *opts; 722 { 723 register struct ip *ip = mtod(m, struct ip *); 724 register int hlen; 725 register struct icmp *icp; 726 struct route ro; 727 728 hlen = IP_VHL_HL(ip->ip_vhl) << 2; 729 m->m_data += hlen; 730 m->m_len -= hlen; 731 icp = mtod(m, struct icmp *); 732 icp->icmp_cksum = 0; 733 icp->icmp_cksum = in_cksum(m, ip->ip_len - hlen); 734 m->m_data -= hlen; 735 m->m_len += hlen; 736 m->m_pkthdr.rcvif = (struct ifnet *)0; 737 #ifdef ICMPPRINTFS 738 if (icmpprintfs) { 739 char buf[4 * sizeof "123"]; 740 strcpy(buf, inet_ntoa(ip->ip_dst)); 741 printf("icmp_send dst %s src %s\n", 742 buf, inet_ntoa(ip->ip_src)); 743 } 744 #endif 745 bzero(&ro, sizeof ro); 746 (void) ip_output(m, opts, &ro, 0, NULL); 747 if (ro.ro_rt) 748 RTFREE(ro.ro_rt); 749 } 750 751 n_time 752 iptime() 753 { 754 struct timeval atv; 755 u_long t; 756 757 getmicrotime(&atv); 758 t = (atv.tv_sec % (24*60*60)) * 1000 + atv.tv_usec / 1000; 759 return (htonl(t)); 760 } 761 762 #if 1 763 /* 764 * Return the next larger or smaller MTU plateau (table from RFC 1191) 765 * given current value MTU. If DIR is less than zero, a larger plateau 766 * is returned; otherwise, a smaller value is returned. 767 */ 768 static int 769 ip_next_mtu(mtu, dir) 770 int mtu; 771 int dir; 772 { 773 static int mtutab[] = { 774 65535, 32000, 17914, 8166, 4352, 2002, 1492, 1006, 508, 296, 775 68, 0 776 }; 777 int i; 778 779 for (i = 0; i < (sizeof mtutab) / (sizeof mtutab[0]); i++) { 780 if (mtu >= mtutab[i]) 781 break; 782 } 783 784 if (dir < 0) { 785 if (i == 0) { 786 return 0; 787 } else { 788 return mtutab[i - 1]; 789 } 790 } else { 791 if (mtutab[i] == 0) { 792 return 0; 793 } else if(mtu > mtutab[i]) { 794 return mtutab[i]; 795 } else { 796 return mtutab[i + 1]; 797 } 798 } 799 } 800 #endif 801 802 803 /* 804 * badport_bandlim() - check for ICMP bandwidth limit 805 * 806 * Return 0 if it is ok to send an ICMP error response, -1 if we have 807 * hit our bandwidth limit and it is not ok. 808 * 809 * If icmplim is <= 0, the feature is disabled and 0 is returned. 810 * 811 * For now we separate the TCP and UDP subsystems w/ different 'which' 812 * values. We may eventually remove this separation (and simplify the 813 * code further). 814 * 815 * Note that the printing of the error message is delayed so we can 816 * properly print the icmp error rate that the system was trying to do 817 * (i.e. 22000/100 pps, etc...). This can cause long delays in printing 818 * the 'final' error, but it doesn't make sense to solve the printing 819 * delay with more complex code. 820 */ 821 822 int 823 badport_bandlim(int which) 824 { 825 static int lticks[BANDLIM_MAX + 1]; 826 static int lpackets[BANDLIM_MAX + 1]; 827 int dticks; 828 const char *bandlimittype[] = { 829 "Limiting icmp unreach response", 830 "Limiting icmp ping response", 831 "Limiting icmp tstamp response", 832 "Limiting closed port RST response", 833 "Limiting open port RST response" 834 }; 835 836 /* 837 * Return ok status if feature disabled or argument out of 838 * ranage. 839 */ 840 841 if (icmplim <= 0 || which > BANDLIM_MAX || which < 0) 842 return(0); 843 dticks = ticks - lticks[which]; 844 845 /* 846 * reset stats when cumulative dt exceeds one second. 847 */ 848 849 if ((unsigned int)dticks > hz) { 850 if (lpackets[which] > icmplim && icmplim_output) { 851 printf("%s from %d to %d packets per second\n", 852 bandlimittype[which], 853 lpackets[which], 854 icmplim 855 ); 856 } 857 lticks[which] = ticks; 858 lpackets[which] = 0; 859 } 860 861 /* 862 * bump packet count 863 */ 864 865 if (++lpackets[which] > icmplim) { 866 return(-1); 867 } 868 return(0); 869 } 870 871