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