1/* 2 * Copyright (c) 2000-2013 Apple Inc. All rights reserved. 3 * 4 * @APPLE_OSREFERENCE_LICENSE_HEADER_START@ 5 * 6 * This file contains Original Code and/or Modifications of Original Code 7 * as defined in and that are subject to the Apple Public Source License 8 * Version 2.0 (the 'License'). You may not use this file except in 9 * compliance with the License. The rights granted to you under the License 10 * may not be used to create, or enable the creation or redistribution of, 11 * unlawful or unlicensed copies of an Apple operating system, or to 12 * circumvent, violate, or enable the circumvention or violation of, any 13 * terms of an Apple operating system software license agreement. 14 * 15 * Please obtain a copy of the License at 16 * http://www.opensource.apple.com/apsl/ and read it before using this file. 17 * 18 * The Original Code and all software distributed under the License are 19 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER 20 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, 21 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, 22 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. 23 * Please see the License for the specific language governing rights and 24 * limitations under the License. 25 * 26 * @APPLE_OSREFERENCE_LICENSE_HEADER_END@ 27 */ 28/* 29 * Copyright (c) 1982, 1986, 1988, 1993 30 * The Regents of the University of California. All rights reserved. 31 * 32 * Redistribution and use in source and binary forms, with or without 33 * modification, are permitted provided that the following conditions 34 * are met: 35 * 1. Redistributions of source code must retain the above copyright 36 * notice, this list of conditions and the following disclaimer. 37 * 2. Redistributions in binary form must reproduce the above copyright 38 * notice, this list of conditions and the following disclaimer in the 39 * documentation and/or other materials provided with the distribution. 40 * 3. All advertising materials mentioning features or use of this software 41 * must display the following acknowledgement: 42 * This product includes software developed by the University of 43 * California, Berkeley and its contributors. 44 * 4. Neither the name of the University nor the names of its contributors 45 * may be used to endorse or promote products derived from this software 46 * without specific prior written permission. 47 * 48 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 49 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 50 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 51 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 52 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 53 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 54 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 55 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 56 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 57 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 58 * SUCH DAMAGE. 59 * 60 * @(#)ip_icmp.c 8.2 (Berkeley) 1/4/94 61 */ 62/* 63 * NOTICE: This file was modified by SPARTA, Inc. in 2005 to introduce 64 * support for mandatory and extensible security protections. This notice 65 * is included in support of clause 2.2 (b) of the Apple Public License, 66 * Version 2.0. 67 */ 68 69#include <sys/param.h> 70#include <sys/systm.h> 71#include <sys/mbuf.h> 72#include <sys/mcache.h> 73#include <sys/protosw.h> 74#include <sys/socket.h> 75#include <sys/time.h> 76#include <sys/kernel.h> 77#include <sys/sysctl.h> 78 79#include <machine/endian.h> 80 81#include <net/if.h> 82#include <net/route.h> 83 84#define _IP_VHL 85#include <netinet/in.h> 86#include <netinet/in_systm.h> 87#include <netinet/in_var.h> 88#include <netinet/ip.h> 89#include <netinet/ip_icmp.h> 90#include <netinet/ip_var.h> 91#include <netinet/icmp_var.h> 92#include <netinet/tcp.h> 93#include <netinet/tcp_fsm.h> 94#include <netinet/tcp_seq.h> 95#include <netinet/tcp_timer.h> 96#include <netinet/tcp_var.h> 97#include <netinet/tcpip.h> 98 99#if IPSEC 100#include <netinet6/ipsec.h> 101#include <netkey/key.h> 102#endif 103 104#if NECP 105#include <net/necp.h> 106#endif /* NECP */ 107 108 /* XXX This one should go in sys/mbuf.h. It is used to avoid that 109 * a firewall-generated packet loops forever through the firewall. 110 */ 111#ifndef M_SKIP_FIREWALL 112#define M_SKIP_FIREWALL 0x4000 113#endif 114 115#if CONFIG_MACF_NET 116#include <security/mac_framework.h> 117#endif /* MAC_NET */ 118 119 120/* 121 * ICMP routines: error generation, receive packet processing, and 122 * routines to turnaround packets back to the originator, and 123 * host table maintenance routines. 124 */ 125 126struct icmpstat icmpstat; 127SYSCTL_STRUCT(_net_inet_icmp, ICMPCTL_STATS, stats, CTLFLAG_RD | CTLFLAG_LOCKED, 128 &icmpstat, icmpstat, ""); 129 130static int icmpmaskrepl = 0; 131SYSCTL_INT(_net_inet_icmp, ICMPCTL_MASKREPL, maskrepl, CTLFLAG_RW | CTLFLAG_LOCKED, 132 &icmpmaskrepl, 0, ""); 133 134static int icmptimestamp = 0; 135SYSCTL_INT(_net_inet_icmp, ICMPCTL_TIMESTAMP, timestamp, CTLFLAG_RW | CTLFLAG_LOCKED, 136 &icmptimestamp, 0, ""); 137 138static int drop_redirect = 0; 139SYSCTL_INT(_net_inet_icmp, OID_AUTO, drop_redirect, CTLFLAG_RW | CTLFLAG_LOCKED, 140 &drop_redirect, 0, ""); 141 142static int log_redirect = 0; 143SYSCTL_INT(_net_inet_icmp, OID_AUTO, log_redirect, CTLFLAG_RW | CTLFLAG_LOCKED, 144 &log_redirect, 0, ""); 145 146#if ICMP_BANDLIM 147 148/* Default values in case CONFIG_ICMP_BANDLIM is not defined in the MASTER file */ 149#ifndef CONFIG_ICMP_BANDLIM 150#define CONFIG_ICMP_BANDLIM 250 151#endif /* CONFIG_ICMP_BANDLIM */ 152 153/* 154 * ICMP error-response bandwidth limiting sysctl. If not enabled, sysctl 155 * variable content is -1 and read-only. 156 */ 157 158static int icmplim = CONFIG_ICMP_BANDLIM; 159SYSCTL_INT(_net_inet_icmp, ICMPCTL_ICMPLIM, icmplim, CTLFLAG_RW | CTLFLAG_LOCKED, 160 &icmplim, 0, ""); 161 162#else /* ICMP_BANDLIM */ 163 164static int icmplim = -1; 165SYSCTL_INT(_net_inet_icmp, ICMPCTL_ICMPLIM, icmplim, CTLFLAG_RD | CTLFLAG_LOCKED, 166 &icmplim, 0, ""); 167 168#endif /* ICMP_BANDLIM */ 169 170/* 171 * ICMP broadcast echo sysctl 172 */ 173 174static int icmpbmcastecho = 1; 175SYSCTL_INT(_net_inet_icmp, OID_AUTO, bmcastecho, CTLFLAG_RW | CTLFLAG_LOCKED, 176 &icmpbmcastecho, 0, ""); 177 178 179#if ICMPPRINTFS 180int icmpprintfs = 0; 181#endif 182 183static void icmp_reflect(struct mbuf *); 184static void icmp_send(struct mbuf *, struct mbuf *); 185 186/* 187 * Generate an error packet of type error 188 * in response to bad packet ip. 189 */ 190void 191icmp_error( 192 struct mbuf *n, 193 int type, 194 int code, 195 n_long dest, 196 u_int32_t nextmtu) 197{ 198 struct ip *oip = mtod(n, struct ip *), *nip; 199 unsigned oiplen; 200 struct icmp *icp; 201 struct mbuf *m; 202 unsigned icmplen; 203 204 /* Expect 32-bit aligned data pointer on strict-align platforms */ 205 MBUF_STRICT_DATA_ALIGNMENT_CHECK_32(n); 206 207 oiplen = IP_VHL_HL(oip->ip_vhl) << 2; 208 209#if ICMPPRINTFS 210 if (icmpprintfs) 211 printf("icmp_error(0x%llx, %x, %d)\n", 212 (uint64_t)VM_KERNEL_ADDRPERM(oip), type, code); 213#endif 214 if (type != ICMP_REDIRECT) 215 icmpstat.icps_error++; 216 /* 217 * Don't send error if not the first fragment of message. 218 * Don't error if the old packet protocol was ICMP 219 * error message, only known informational types. 220 */ 221 if (oip->ip_off &~ (IP_MF|IP_DF)) 222 goto freeit; 223 if (oip->ip_p == IPPROTO_ICMP && type != ICMP_REDIRECT && 224 n->m_len >= oiplen + ICMP_MINLEN && 225 !ICMP_INFOTYPE(((struct icmp *)(void *)((caddr_t)oip + oiplen))-> 226 icmp_type)) { 227 icmpstat.icps_oldicmp++; 228 goto freeit; 229 } 230 /* Don't send error in response to a multicast or broadcast packet */ 231 if (n->m_flags & (M_BCAST|M_MCAST)) 232 goto freeit; 233 /* 234 * First, formulate icmp message 235 */ 236 m = m_gethdr(M_DONTWAIT, MT_HEADER); /* MAC-OK */ 237 if (m == NULL) 238 goto freeit; 239 240 if (n->m_flags & M_SKIP_FIREWALL) { 241 /* set M_SKIP_FIREWALL to skip firewall check, since we're called from firewall */ 242 m->m_flags |= M_SKIP_FIREWALL; 243 } 244 245#if CONFIG_MACF_NET 246 mac_mbuf_label_associate_netlayer(n, m); 247#endif 248 icmplen = min(oiplen + 8, oip->ip_len); 249 if (icmplen < sizeof(struct ip)) { 250 printf("icmp_error: bad length\n"); 251 m_free(m); 252 goto freeit; 253 } 254 m->m_len = icmplen + ICMP_MINLEN; 255 MH_ALIGN(m, m->m_len); 256 icp = mtod(m, struct icmp *); 257 if ((u_int)type > ICMP_MAXTYPE) 258 panic("icmp_error"); 259 icmpstat.icps_outhist[type]++; 260 icp->icmp_type = type; 261 if (type == ICMP_REDIRECT) 262 icp->icmp_gwaddr.s_addr = dest; 263 else { 264 icp->icmp_void = 0; 265 /* 266 * The following assignments assume an overlay with the 267 * zeroed icmp_void field. 268 */ 269 if (type == ICMP_PARAMPROB) { 270 icp->icmp_pptr = code; 271 code = 0; 272 } else if (type == ICMP_UNREACH && 273 code == ICMP_UNREACH_NEEDFRAG && nextmtu != 0) { 274 icp->icmp_nextmtu = htons(nextmtu); 275 } 276 } 277 278 icp->icmp_code = code; 279 m_copydata(n, 0, icmplen, (caddr_t)&icp->icmp_ip); 280 nip = &icp->icmp_ip; 281 282 /* 283 * Convert fields to network representation. 284 */ 285#if BYTE_ORDER != BIG_ENDIAN 286 HTONS(nip->ip_len); 287 HTONS(nip->ip_off); 288#endif 289 /* 290 * Now, copy old ip header (without options) 291 * in front of icmp message. 292 */ 293 if (m->m_data - sizeof(struct ip) < m->m_pktdat) 294 panic("icmp len"); 295 m->m_data -= sizeof(struct ip); 296 m->m_len += sizeof(struct ip); 297 m->m_pkthdr.len = m->m_len; 298 m->m_pkthdr.rcvif = n->m_pkthdr.rcvif; 299 nip = mtod(m, struct ip *); 300 bcopy((caddr_t)oip, (caddr_t)nip, sizeof(struct ip)); 301 nip->ip_len = m->m_len; 302 nip->ip_vhl = IP_VHL_BORING; 303 nip->ip_p = IPPROTO_ICMP; 304 nip->ip_tos = 0; 305 icmp_reflect(m); 306 307freeit: 308 m_freem(n); 309} 310 311/* 312 * Process a received ICMP message. 313 */ 314void 315icmp_input(struct mbuf *m, int hlen) 316{ 317 struct sockaddr_in icmpsrc, icmpdst, icmpgw; 318 struct icmp *icp; 319 struct ip *ip = mtod(m, struct ip *); 320 int icmplen; 321 int i; 322 struct in_ifaddr *ia; 323 void (*ctlfunc)(int, struct sockaddr *, void *); 324 int code; 325 326 /* Expect 32-bit aligned data pointer on strict-align platforms */ 327 MBUF_STRICT_DATA_ALIGNMENT_CHECK_32(m); 328 329 icmplen = ip->ip_len; 330 331 /* 332 * Locate icmp structure in mbuf, and check 333 * that not corrupted and of at least minimum length. 334 */ 335#if ICMPPRINTFS 336 if (icmpprintfs) { 337 char buf[MAX_IPv4_STR_LEN]; 338 char ipv4str[MAX_IPv4_STR_LEN]; 339 340 printf("icmp_input from %s to %s, len %d\n", 341 inet_ntop(AF_INET, &ip->ip_src, buf, sizeof(buf)), 342 inet_ntop(AF_INET, &ip->ip_dst, ipv4str, sizeof(ipv4str)), 343 icmplen); 344 } 345#endif 346 if (icmplen < ICMP_MINLEN) { 347 icmpstat.icps_tooshort++; 348 goto freeit; 349 } 350 i = hlen + min(icmplen, ICMP_ADVLENMIN); 351 if (m->m_len < i && (m = m_pullup(m, i)) == 0) { 352 icmpstat.icps_tooshort++; 353 return; 354 } 355 ip = mtod(m, struct ip *); 356 m->m_len -= hlen; 357 m->m_data += hlen; 358 icp = mtod(m, struct icmp *); 359 if (in_cksum(m, icmplen)) { 360 icmpstat.icps_checksum++; 361 goto freeit; 362 } 363 m->m_len += hlen; 364 m->m_data -= hlen; 365 366#if ICMPPRINTFS 367 if (icmpprintfs) 368 printf("icmp_input, type %d code %d\n", icp->icmp_type, 369 icp->icmp_code); 370#endif 371 372 /* 373 * Message type specific processing. 374 */ 375 if (icp->icmp_type > ICMP_MAXTYPE) 376 goto raw; 377 378 /* Initialize */ 379 bzero(&icmpsrc, sizeof (icmpsrc)); 380 icmpsrc.sin_len = sizeof (struct sockaddr_in); 381 icmpsrc.sin_family = AF_INET; 382 bzero(&icmpdst, sizeof (icmpdst)); 383 icmpdst.sin_len = sizeof (struct sockaddr_in); 384 icmpdst.sin_family = AF_INET; 385 bzero(&icmpgw, sizeof (icmpgw)); 386 icmpgw.sin_len = sizeof (struct sockaddr_in); 387 icmpgw.sin_family = AF_INET; 388 389 icmpstat.icps_inhist[icp->icmp_type]++; 390 code = icp->icmp_code; 391 switch (icp->icmp_type) { 392 393 case ICMP_UNREACH: 394 switch (code) { 395 case ICMP_UNREACH_NET: 396 case ICMP_UNREACH_HOST: 397 case ICMP_UNREACH_SRCFAIL: 398 case ICMP_UNREACH_NET_UNKNOWN: 399 case ICMP_UNREACH_HOST_UNKNOWN: 400 case ICMP_UNREACH_ISOLATED: 401 case ICMP_UNREACH_TOSNET: 402 case ICMP_UNREACH_TOSHOST: 403 case ICMP_UNREACH_HOST_PRECEDENCE: 404 case ICMP_UNREACH_PRECEDENCE_CUTOFF: 405 code = PRC_UNREACH_NET; 406 break; 407 408 case ICMP_UNREACH_NEEDFRAG: 409 code = PRC_MSGSIZE; 410 break; 411 412 /* 413 * RFC 1122, Sections 3.2.2.1 and 4.2.3.9. 414 * Treat subcodes 2,3 as immediate RST 415 */ 416 case ICMP_UNREACH_PROTOCOL: 417 case ICMP_UNREACH_PORT: 418 code = PRC_UNREACH_PORT; 419 break; 420 421 case ICMP_UNREACH_NET_PROHIB: 422 case ICMP_UNREACH_HOST_PROHIB: 423 case ICMP_UNREACH_FILTER_PROHIB: 424 code = PRC_UNREACH_ADMIN_PROHIB; 425 break; 426 427 default: 428 goto badcode; 429 } 430 goto deliver; 431 432 case ICMP_TIMXCEED: 433 if (code > 1) 434 goto badcode; 435 code += PRC_TIMXCEED_INTRANS; 436 goto deliver; 437 438 case ICMP_PARAMPROB: 439 if (code > 1) 440 goto badcode; 441 code = PRC_PARAMPROB; 442 goto deliver; 443 444 case ICMP_SOURCEQUENCH: 445 if (code) 446 goto badcode; 447 code = PRC_QUENCH; 448 deliver: 449 /* 450 * Problem with datagram; advise higher level routines. 451 */ 452 if (icmplen < ICMP_ADVLENMIN || icmplen < ICMP_ADVLEN(icp) || 453 IP_VHL_HL(icp->icmp_ip.ip_vhl) < (sizeof(struct ip) >> 2)) { 454 icmpstat.icps_badlen++; 455 goto freeit; 456 } 457 458#if BYTE_ORDER != BIG_ENDIAN 459 NTOHS(icp->icmp_ip.ip_len); 460#endif 461 462 /* Discard ICMP's in response to multicast packets */ 463 if (IN_MULTICAST(ntohl(icp->icmp_ip.ip_dst.s_addr))) 464 goto badcode; 465#if ICMPPRINTFS 466 if (icmpprintfs) 467 printf("deliver to protocol %d\n", icp->icmp_ip.ip_p); 468#endif 469 icmpsrc.sin_addr = icp->icmp_ip.ip_dst; 470 471 /* 472 * XXX if the packet contains [IPv4 AH TCP], we can't make a 473 * notification to TCP layer. 474 */ 475 ctlfunc = ip_protox[icp->icmp_ip.ip_p]->pr_ctlinput; 476 if (ctlfunc) 477 (*ctlfunc)(code, (struct sockaddr *)&icmpsrc, 478 (void *)&icp->icmp_ip); 479 break; 480 481 badcode: 482 icmpstat.icps_badcode++; 483 break; 484 485 case ICMP_ECHO: 486 if (!icmpbmcastecho 487 && (m->m_flags & (M_MCAST | M_BCAST)) != 0) { 488 icmpstat.icps_bmcastecho++; 489 break; 490 } 491 icp->icmp_type = ICMP_ECHOREPLY; 492#if ICMP_BANDLIM 493 if (badport_bandlim(BANDLIM_ICMP_ECHO) < 0) 494 goto freeit; 495 else 496#endif 497 goto reflect; 498 499 case ICMP_TSTAMP: 500 501 if (icmptimestamp == 0) 502 break; 503 504 if (!icmpbmcastecho 505 && (m->m_flags & (M_MCAST | M_BCAST)) != 0) { 506 icmpstat.icps_bmcasttstamp++; 507 break; 508 } 509 if (icmplen < ICMP_TSLEN) { 510 icmpstat.icps_badlen++; 511 break; 512 } 513 icp->icmp_type = ICMP_TSTAMPREPLY; 514 icp->icmp_rtime = iptime(); 515 icp->icmp_ttime = icp->icmp_rtime; /* bogus, do later! */ 516#if ICMP_BANDLIM 517 if (badport_bandlim(BANDLIM_ICMP_TSTAMP) < 0) 518 goto freeit; 519 else 520#endif 521 goto reflect; 522 523 case ICMP_MASKREQ: 524 if (icmpmaskrepl == 0) 525 break; 526 /* 527 * We are not able to respond with all ones broadcast 528 * unless we receive it over a point-to-point interface. 529 */ 530 if (icmplen < ICMP_MASKLEN) 531 break; 532 switch (ip->ip_dst.s_addr) { 533 534 case INADDR_BROADCAST: 535 case INADDR_ANY: 536 icmpdst.sin_addr = ip->ip_src; 537 break; 538 539 default: 540 icmpdst.sin_addr = ip->ip_dst; 541 } 542 ia = (struct in_ifaddr *)ifaof_ifpforaddr( 543 (struct sockaddr *)&icmpdst, m->m_pkthdr.rcvif); 544 if (ia == 0) 545 break; 546 IFA_LOCK(&ia->ia_ifa); 547 if (ia->ia_ifp == 0) { 548 IFA_UNLOCK(&ia->ia_ifa); 549 IFA_REMREF(&ia->ia_ifa); 550 ia = NULL; 551 break; 552 } 553 icp->icmp_type = ICMP_MASKREPLY; 554 icp->icmp_mask = ia->ia_sockmask.sin_addr.s_addr; 555 if (ip->ip_src.s_addr == 0) { 556 if (ia->ia_ifp->if_flags & IFF_BROADCAST) 557 ip->ip_src = satosin(&ia->ia_broadaddr)->sin_addr; 558 else if (ia->ia_ifp->if_flags & IFF_POINTOPOINT) 559 ip->ip_src = satosin(&ia->ia_dstaddr)->sin_addr; 560 } 561 IFA_UNLOCK(&ia->ia_ifa); 562 IFA_REMREF(&ia->ia_ifa); 563reflect: 564 ip->ip_len += hlen; /* since ip_input deducts this */ 565 icmpstat.icps_reflect++; 566 icmpstat.icps_outhist[icp->icmp_type]++; 567 icmp_reflect(m); 568 return; 569 570 case ICMP_REDIRECT: 571 if (log_redirect) { 572 u_int32_t src, dst, gw; 573 574 src = ntohl(ip->ip_src.s_addr); 575 dst = ntohl(icp->icmp_ip.ip_dst.s_addr); 576 gw = ntohl(icp->icmp_gwaddr.s_addr); 577 printf("icmp redirect from %d.%d.%d.%d: " 578 "%d.%d.%d.%d => %d.%d.%d.%d\n", 579 (int)(src >> 24), (int)((src >> 16) & 0xff), 580 (int)((src >> 8) & 0xff), (int)(src & 0xff), 581 (int)(dst >> 24), (int)((dst >> 16) & 0xff), 582 (int)((dst >> 8) & 0xff), (int)(dst & 0xff), 583 (int)(gw >> 24), (int)((gw >> 16) & 0xff), 584 (int)((gw >> 8) & 0xff), (int)(gw & 0xff)); 585 } 586 if (drop_redirect) 587 break; 588 if (code > 3) 589 goto badcode; 590 if (icmplen < ICMP_ADVLENMIN || icmplen < ICMP_ADVLEN(icp) || 591 IP_VHL_HL(icp->icmp_ip.ip_vhl) < (sizeof(struct ip) >> 2)) { 592 icmpstat.icps_badlen++; 593 break; 594 } 595 /* 596 * Short circuit routing redirects to force 597 * immediate change in the kernel's routing 598 * tables. The message is also handed to anyone 599 * listening on a raw socket (e.g. the routing 600 * daemon for use in updating its tables). 601 */ 602 icmpgw.sin_addr = ip->ip_src; 603 icmpdst.sin_addr = icp->icmp_gwaddr; 604#if ICMPPRINTFS 605 if (icmpprintfs) { 606 char buf[MAX_IPv4_STR_LEN]; 607 608 printf("redirect dst %s to %s\n", 609 inet_ntop(AF_INET, &icp->icmp_ip.ip_dst, buf, sizeof(buf)), 610 inet_ntop(AF_INET, &icp->icmp_gwaddr, ipv4str, 611 sizeof(ipv4str))); 612 } 613#endif 614 icmpsrc.sin_addr = icp->icmp_ip.ip_dst; 615 rtredirect(m->m_pkthdr.rcvif, (struct sockaddr *)&icmpsrc, 616 (struct sockaddr *)&icmpdst, NULL, RTF_GATEWAY | RTF_HOST, 617 (struct sockaddr *)&icmpgw, NULL); 618 pfctlinput(PRC_REDIRECT_HOST, (struct sockaddr *)&icmpsrc); 619#if IPSEC 620 key_sa_routechange((struct sockaddr *)&icmpsrc); 621#endif 622 break; 623 624 /* 625 * No kernel processing for the following; 626 * just fall through to send to raw listener. 627 */ 628 case ICMP_ECHOREPLY: 629 case ICMP_ROUTERADVERT: 630 case ICMP_ROUTERSOLICIT: 631 case ICMP_TSTAMPREPLY: 632 case ICMP_IREQREPLY: 633 case ICMP_MASKREPLY: 634 default: 635 break; 636 } 637 638raw: 639 rip_input(m, hlen); 640 return; 641 642freeit: 643 m_freem(m); 644} 645 646/* 647 * Reflect the ip packet back to the source 648 */ 649static void 650icmp_reflect(struct mbuf *m) 651{ 652 struct ip *ip = mtod(m, struct ip *); 653 struct sockaddr_in icmpdst; 654 struct in_ifaddr *ia; 655 struct in_addr t; 656 struct mbuf *opts = NULL; 657 int optlen = (IP_VHL_HL(ip->ip_vhl) << 2) - sizeof(struct ip); 658 659 if (!in_canforward(ip->ip_src) && 660 ((ntohl(ip->ip_src.s_addr) & IN_CLASSA_NET) != 661 (IN_LOOPBACKNET << IN_CLASSA_NSHIFT))) { 662 m_freem(m); /* Bad return address */ 663 goto done; /* Ip_output() will check for broadcast */ 664 } 665 t = ip->ip_dst; 666 ip->ip_dst = ip->ip_src; 667 /* 668 * If the incoming packet was addressed directly to us, 669 * use dst as the src for the reply. Otherwise (broadcast 670 * or anonymous), use the address which corresponds 671 * to the incoming interface. 672 */ 673 lck_rw_lock_shared(in_ifaddr_rwlock); 674 TAILQ_FOREACH(ia, INADDR_HASH(t.s_addr), ia_hash) { 675 IFA_LOCK(&ia->ia_ifa); 676 if (t.s_addr == IA_SIN(ia)->sin_addr.s_addr) { 677 IFA_ADDREF_LOCKED(&ia->ia_ifa); 678 IFA_UNLOCK(&ia->ia_ifa); 679 goto match; 680 } 681 IFA_UNLOCK(&ia->ia_ifa); 682 } 683 /* 684 * Slow path; check for broadcast addresses. Find a source 685 * IP address to use when replying to the broadcast request; 686 * let IP handle the source interface selection work. 687 */ 688 for (ia = in_ifaddrhead.tqh_first; ia; ia = ia->ia_link.tqe_next) { 689 IFA_LOCK(&ia->ia_ifa); 690 if (ia->ia_ifp && (ia->ia_ifp->if_flags & IFF_BROADCAST) && 691 t.s_addr == satosin(&ia->ia_broadaddr)->sin_addr.s_addr) { 692 IFA_ADDREF_LOCKED(&ia->ia_ifa); 693 IFA_UNLOCK(&ia->ia_ifa); 694 break; 695 } 696 IFA_UNLOCK(&ia->ia_ifa); 697 } 698match: 699 lck_rw_done(in_ifaddr_rwlock); 700 701 /* Initialize */ 702 bzero(&icmpdst, sizeof (icmpdst)); 703 icmpdst.sin_len = sizeof (struct sockaddr_in); 704 icmpdst.sin_family = AF_INET; 705 icmpdst.sin_addr = t; 706 if ((ia == (struct in_ifaddr *)0) && m->m_pkthdr.rcvif) 707 ia = (struct in_ifaddr *)ifaof_ifpforaddr( 708 (struct sockaddr *)&icmpdst, m->m_pkthdr.rcvif); 709 /* 710 * The following happens if the packet was not addressed to us, 711 * and was received on an interface with no IP address. 712 */ 713 if (ia == (struct in_ifaddr *)0) { 714 lck_rw_lock_shared(in_ifaddr_rwlock); 715 ia = in_ifaddrhead.tqh_first; 716 if (ia == (struct in_ifaddr *)0) {/* no address yet, bail out */ 717 lck_rw_done(in_ifaddr_rwlock); 718 m_freem(m); 719 goto done; 720 } 721 IFA_ADDREF(&ia->ia_ifa); 722 lck_rw_done(in_ifaddr_rwlock); 723 } 724#if CONFIG_MACF_NET 725 mac_netinet_icmp_reply(m); 726#endif 727 IFA_LOCK_SPIN(&ia->ia_ifa); 728 t = IA_SIN(ia)->sin_addr; 729 IFA_UNLOCK(&ia->ia_ifa); 730 ip->ip_src = t; 731 ip->ip_ttl = ip_defttl; 732 IFA_REMREF(&ia->ia_ifa); 733 ia = NULL; 734 735 if (optlen > 0) { 736 u_char *cp; 737 int opt, cnt; 738 u_int len; 739 740 /* 741 * Retrieve any source routing from the incoming packet; 742 * add on any record-route or timestamp options. 743 */ 744 cp = (u_char *) (ip + 1); 745 if ((opts = ip_srcroute()) == 0 && 746 (opts = m_gethdr(M_DONTWAIT, MT_HEADER))) { /* MAC-OK */ 747 opts->m_len = sizeof(struct in_addr); 748 mtod(opts, struct in_addr *)->s_addr = 0; 749 } 750 if (opts) { 751#if ICMPPRINTFS 752 if (icmpprintfs) 753 printf("icmp_reflect optlen %d rt %d => ", 754 optlen, opts->m_len); 755#endif 756 for (cnt = optlen; cnt > 0; cnt -= len, cp += len) { 757 opt = cp[IPOPT_OPTVAL]; 758 if (opt == IPOPT_EOL) 759 break; 760 if (opt == IPOPT_NOP) 761 len = 1; 762 else { 763 if (cnt < IPOPT_OLEN + sizeof(*cp)) 764 break; 765 len = cp[IPOPT_OLEN]; 766 if (len < IPOPT_OLEN + sizeof(*cp) || 767 len > cnt) 768 break; 769 } 770 /* 771 * Should check for overflow, but it "can't happen" 772 */ 773 if (opt == IPOPT_RR || opt == IPOPT_TS || 774 opt == IPOPT_SECURITY) { 775 bcopy((caddr_t)cp, 776 mtod(opts, caddr_t) + opts->m_len, len); 777 opts->m_len += len; 778 } 779 } 780 /* Terminate & pad, if necessary */ 781 cnt = opts->m_len % 4; 782 if (cnt) { 783 for (; cnt < 4; cnt++) { 784 *(mtod(opts, caddr_t) + opts->m_len) = 785 IPOPT_EOL; 786 opts->m_len++; 787 } 788 } 789#if ICMPPRINTFS 790 if (icmpprintfs) 791 printf("%d\n", opts->m_len); 792#endif 793 } 794 /* 795 * Now strip out original options by copying rest of first 796 * mbuf's data back, and adjust the IP length. 797 */ 798 ip->ip_len -= optlen; 799 ip->ip_vhl = IP_VHL_BORING; 800 m->m_len -= optlen; 801 if (m->m_flags & M_PKTHDR) 802 m->m_pkthdr.len -= optlen; 803 optlen += sizeof(struct ip); 804 bcopy((caddr_t)ip + optlen, (caddr_t)(ip + 1), 805 (unsigned)(m->m_len - sizeof(struct ip))); 806 } 807 m->m_flags &= ~(M_BCAST|M_MCAST); 808 icmp_send(m, opts); 809done: 810 if (opts) 811 (void)m_free(opts); 812} 813 814/* 815 * Send an icmp packet back to the ip level, 816 * after supplying a checksum. 817 */ 818static void 819icmp_send(struct mbuf *m, struct mbuf *opts) 820{ 821 struct ip *ip = mtod(m, struct ip *); 822 int hlen; 823 struct icmp *icp; 824 struct route ro; 825 struct ip_out_args ipoa = { IFSCOPE_NONE, { 0 }, 826 IPOAF_SELECT_SRCIF | IPOAF_BOUND_SRCADDR, 0 }; 827 828 if (!(m->m_pkthdr.pkt_flags & PKTF_LOOP) && m->m_pkthdr.rcvif != NULL) { 829 ipoa.ipoa_boundif = m->m_pkthdr.rcvif->if_index; 830 ipoa.ipoa_flags |= IPOAF_BOUND_IF; 831 } 832 833 hlen = IP_VHL_HL(ip->ip_vhl) << 2; 834 m->m_data += hlen; 835 m->m_len -= hlen; 836 icp = mtod(m, struct icmp *); 837 icp->icmp_cksum = 0; 838 icp->icmp_cksum = in_cksum(m, ip->ip_len - hlen); 839 m->m_data -= hlen; 840 m->m_len += hlen; 841 m->m_pkthdr.rcvif = NULL; 842 m->m_pkthdr.csum_data = 0; 843 m->m_pkthdr.csum_flags = 0; 844#if ICMPPRINTFS 845 if (icmpprintfs) { 846 char buf[MAX_IPv4_STR_LEN]; 847 char ipv4str[MAX_IPv4_STR_LEN]; 848 849 printf("icmp_send dst %s src %s\n", 850 inet_ntop(AF_INET, &ip->ip_dst, buf, sizeof(buf)), 851 inet_ntop(AF_INET, &ip->ip_src, ipv4str, sizeof(ipv4str))); 852 } 853#endif 854 bzero(&ro, sizeof ro); 855 (void) ip_output(m, opts, &ro, IP_OUTARGS, NULL, &ipoa); 856 ROUTE_RELEASE(&ro); 857} 858 859n_time 860iptime(void) 861{ 862 struct timeval atv; 863 u_int32_t t; 864 865 getmicrotime(&atv); 866 t = (atv.tv_sec % (24*60*60)) * 1000 + atv.tv_usec / 1000; 867 return (htonl(t)); 868} 869 870#if 1 871/* 872 * Return the next larger or smaller MTU plateau (table from RFC 1191) 873 * given current value MTU. If DIR is less than zero, a larger plateau 874 * is returned; otherwise, a smaller value is returned. 875 */ 876int 877ip_next_mtu(int mtu, int dir) 878{ 879 static int mtutab[] = { 880 65535, 32000, 17914, 8166, 4352, 2002, 1492, 1006, 508, 296, 881 68, 0 882 }; 883 int i; 884 885 for (i = 0; i < (sizeof mtutab) / (sizeof mtutab[0]); i++) { 886 if (mtu >= mtutab[i]) 887 break; 888 } 889 890 if (dir < 0) { 891 if (i == 0) { 892 return 0; 893 } else { 894 return mtutab[i - 1]; 895 } 896 } else { 897 if (mtutab[i] == 0) { 898 return 0; 899 } else if(mtu > mtutab[i]) { 900 return mtutab[i]; 901 } else { 902 return mtutab[i + 1]; 903 } 904 } 905} 906#endif 907 908#if ICMP_BANDLIM 909 910/* 911 * badport_bandlim() - check for ICMP bandwidth limit 912 * 913 * Return 0 if it is ok to send an ICMP error response, -1 if we have 914 * hit our bandwidth limit and it is not ok. 915 * 916 * If icmplim is <= 0, the feature is disabled and 0 is returned. 917 * 918 * For now we separate the TCP and UDP subsystems w/ different 'which' 919 * values. We may eventually remove this separation (and simplify the 920 * code further). 921 * 922 * Note that the printing of the error message is delayed so we can 923 * properly print the icmp error rate that the system was trying to do 924 * (i.e. 22000/100 pps, etc...). This can cause long delays in printing 925 * the 'final' error, but it doesn't make sense to solve the printing 926 * delay with more complex code. 927 */ 928 929int 930badport_bandlim(int which) 931{ 932 static uint64_t lticks[BANDLIM_MAX + 1]; 933 static int lpackets[BANDLIM_MAX + 1]; 934 uint64_t time = net_uptime(); 935 int secs; 936 937 const char *bandlimittype[] = { 938 "Limiting icmp unreach response", 939 "Limiting icmp ping response", 940 "Limiting icmp tstamp response", 941 "Limiting closed port RST response", 942 "Limiting open port RST response" 943 }; 944 945 /* 946 * Return ok status if feature disabled or argument out of 947 * ranage. 948 */ 949 950 if (icmplim <= 0 || which > BANDLIM_MAX || which < 0) 951 return(0); 952 953 secs = time - lticks[which]; 954 955 /* 956 * reset stats when cumulative delta exceeds one second. 957 */ 958 959 if (secs > 1) { 960 if (lpackets[which] > icmplim) { 961 printf("%s from %d to %d packets per second\n", 962 bandlimittype[which], 963 lpackets[which], 964 icmplim 965 ); 966 } 967 lticks[which] = time; 968 lpackets[which] = 0; 969 } 970 971 /* 972 * bump packet count 973 */ 974 975 if (++lpackets[which] > icmplim) { 976 return(-1); 977 } 978 return(0); 979} 980 981#endif 982 983#if __APPLE__ 984 985/* 986 * Non-privileged ICMP socket operations 987 * - send ICMP echo request 988 * - all ICMP 989 * - limited socket options 990 */ 991 992#include <netinet/ip_icmp.h> 993#include <netinet/in_pcb.h> 994 995extern u_int32_t rip_sendspace; 996extern u_int32_t rip_recvspace; 997extern struct inpcbinfo ripcbinfo; 998 999int rip_abort(struct socket *); 1000int rip_bind(struct socket *, struct sockaddr *, struct proc *); 1001int rip_connect(struct socket *, struct sockaddr *, struct proc *); 1002int rip_detach(struct socket *); 1003int rip_disconnect(struct socket *); 1004int rip_shutdown(struct socket *); 1005 1006__private_extern__ int icmp_dgram_send(struct socket *so, int flags, struct mbuf *m, struct sockaddr *nam, struct mbuf *control, struct proc *p); 1007__private_extern__ int icmp_dgram_attach(struct socket *so, int proto, struct proc *p); 1008__private_extern__ int icmp_dgram_ctloutput(struct socket *so, struct sockopt *sopt); 1009 1010__private_extern__ struct pr_usrreqs icmp_dgram_usrreqs = { 1011 .pru_abort = rip_abort, 1012 .pru_attach = icmp_dgram_attach, 1013 .pru_bind = rip_bind, 1014 .pru_connect = rip_connect, 1015 .pru_control = in_control, 1016 .pru_detach = rip_detach, 1017 .pru_disconnect = rip_disconnect, 1018 .pru_peeraddr = in_getpeeraddr, 1019 .pru_send = icmp_dgram_send, 1020 .pru_shutdown = rip_shutdown, 1021 .pru_sockaddr = in_getsockaddr, 1022 .pru_sosend = sosend, 1023 .pru_soreceive = soreceive, 1024}; 1025 1026/* Like rip_attach but without root privilege enforcement */ 1027__private_extern__ int 1028icmp_dgram_attach(struct socket *so, __unused int proto, struct proc *p) 1029{ 1030 struct inpcb *inp; 1031 int error; 1032 1033 inp = sotoinpcb(so); 1034 if (inp) 1035 panic("icmp_dgram_attach"); 1036 1037 error = soreserve(so, rip_sendspace, rip_recvspace); 1038 if (error) 1039 return error; 1040 error = in_pcballoc(so, &ripcbinfo, p); 1041 if (error) 1042 return error; 1043 inp = (struct inpcb *)so->so_pcb; 1044 inp->inp_vflag |= INP_IPV4; 1045 inp->inp_ip_p = IPPROTO_ICMP; 1046 inp->inp_ip_ttl = ip_defttl; 1047 return 0; 1048} 1049 1050/* 1051 * Raw IP socket option processing. 1052 */ 1053__private_extern__ int 1054icmp_dgram_ctloutput(struct socket *so, struct sockopt *sopt) 1055{ 1056 int error; 1057 1058 if (sopt->sopt_level != IPPROTO_IP) 1059 return (EINVAL); 1060 1061 switch (sopt->sopt_name) { 1062 case IP_OPTIONS: 1063 case IP_HDRINCL: 1064 case IP_TOS: 1065 case IP_TTL: 1066 case IP_RECVOPTS: 1067 case IP_RECVRETOPTS: 1068 case IP_RECVDSTADDR: 1069 case IP_RETOPTS: 1070 case IP_MULTICAST_IF: 1071 case IP_MULTICAST_IFINDEX: 1072 case IP_MULTICAST_TTL: 1073 case IP_MULTICAST_LOOP: 1074 case IP_ADD_MEMBERSHIP: 1075 case IP_DROP_MEMBERSHIP: 1076 case IP_MULTICAST_VIF: 1077 case IP_PORTRANGE: 1078 case IP_RECVIF: 1079 case IP_IPSEC_POLICY: 1080 case IP_STRIPHDR: 1081 case IP_RECVTTL: 1082 case IP_BOUND_IF: 1083#if CONFIG_FORCE_OUT_IFP 1084 case IP_FORCE_OUT_IFP: 1085#endif 1086 case IP_NO_IFT_CELLULAR: 1087 error = rip_ctloutput(so, sopt); 1088 break; 1089 1090 default: 1091 error = EINVAL; 1092 break; 1093 } 1094 1095 return (error); 1096} 1097 1098__private_extern__ int 1099icmp_dgram_send(struct socket *so, int flags, struct mbuf *m, 1100 struct sockaddr *nam, struct mbuf *control, struct proc *p) 1101{ 1102 struct ip *ip; 1103 struct inpcb *inp = sotoinpcb(so); 1104 int hlen; 1105 struct icmp *icp; 1106 struct in_ifaddr *ia = NULL; 1107 int icmplen; 1108 int error = EINVAL; 1109 1110 if (inp == NULL 1111#if NECP 1112 || (necp_socket_should_use_flow_divert(inp)) 1113#endif /* NECP */ 1114 ) { 1115 if (inp != NULL) 1116 error = EPROTOTYPE; 1117 goto bad; 1118 } 1119 1120 if ((inp->inp_flags & INP_HDRINCL) != 0) { 1121 /* Expect 32-bit aligned data ptr on strict-align platforms */ 1122 MBUF_STRICT_DATA_ALIGNMENT_CHECK_32(m); 1123 /* 1124 * This is not raw IP, we liberal only for fields TOS, 1125 * id and TTL. 1126 */ 1127 ip = mtod(m, struct ip *); 1128 1129 hlen = IP_VHL_HL(ip->ip_vhl) << 2; 1130 /* Some sanity checks */ 1131 if (m->m_pkthdr.len < hlen + ICMP_MINLEN) { 1132 goto bad; 1133 } 1134 /* Only IPv4 */ 1135 if (IP_VHL_V(ip->ip_vhl) != 4) 1136 goto bad; 1137 if (hlen < 20 || hlen > 40 || ip->ip_len != m->m_pkthdr.len) 1138 goto bad; 1139 /* Bogus fragments can tie up peer resources */ 1140 if ((ip->ip_off & ~IP_DF) != 0) 1141 goto bad; 1142 /* Allow only ICMP even for user provided IP header */ 1143 if (ip->ip_p != IPPROTO_ICMP) 1144 goto bad; 1145 /* 1146 * To prevent spoofing, specified source address must 1147 * be one of ours. 1148 */ 1149 if (ip->ip_src.s_addr != INADDR_ANY) { 1150 socket_unlock(so, 0); 1151 lck_rw_lock_shared(in_ifaddr_rwlock); 1152 if (TAILQ_EMPTY(&in_ifaddrhead)) { 1153 lck_rw_done(in_ifaddr_rwlock); 1154 socket_lock(so, 0); 1155 goto bad; 1156 } 1157 TAILQ_FOREACH(ia, INADDR_HASH(ip->ip_src.s_addr), 1158 ia_hash) { 1159 IFA_LOCK(&ia->ia_ifa); 1160 if (IA_SIN(ia)->sin_addr.s_addr == 1161 ip->ip_src.s_addr) { 1162 IFA_UNLOCK(&ia->ia_ifa); 1163 lck_rw_done(in_ifaddr_rwlock); 1164 socket_lock(so, 0); 1165 goto ours; 1166 } 1167 IFA_UNLOCK(&ia->ia_ifa); 1168 } 1169 lck_rw_done(in_ifaddr_rwlock); 1170 socket_lock(so, 0); 1171 goto bad; 1172 } 1173ours: 1174 /* Do not trust we got a valid checksum */ 1175 ip->ip_sum = 0; 1176 1177 icp = (struct icmp *)(void *)(((char *)m->m_data) + hlen); 1178 icmplen = m->m_pkthdr.len - hlen; 1179 } else { 1180 if ((icmplen = m->m_pkthdr.len) < ICMP_MINLEN) { 1181 goto bad; 1182 } 1183 icp = mtod(m, struct icmp *); 1184 } 1185 /* 1186 * Allow only to send request types with code 0 1187 */ 1188 if (icp->icmp_code != 0) 1189 goto bad; 1190 switch (icp->icmp_type) { 1191 case ICMP_ECHO: 1192 break; 1193 case ICMP_TSTAMP: 1194 if (icmplen != 20) 1195 goto bad; 1196 break; 1197 case ICMP_MASKREQ: 1198 if (icmplen != 12) 1199 goto bad; 1200 break; 1201 default: 1202 goto bad; 1203 } 1204 return (rip_send(so, flags, m, nam, control, p)); 1205bad: 1206 VERIFY(error != 0); 1207 1208 if (m != NULL) 1209 m_freem(m); 1210 if (control != NULL) 1211 m_freem(control); 1212 1213 return (error); 1214} 1215 1216#endif /* __APPLE__ */ 1217