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