1 /* $NetBSD: ip_icmp.c,v 1.122 2009/12/07 18:47:24 christos Exp $ */ 2 3 /* 4 * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project. 5 * All rights reserved. 6 * 7 * Redistribution and use in source and binary forms, with or without 8 * modification, are permitted provided that the following conditions 9 * are met: 10 * 1. Redistributions of source code must retain the above copyright 11 * notice, this list of conditions and the following disclaimer. 12 * 2. Redistributions in binary form must reproduce the above copyright 13 * notice, this list of conditions and the following disclaimer in the 14 * documentation and/or other materials provided with the distribution. 15 * 3. Neither the name of the project nor the names of its contributors 16 * may be used to endorse or promote products derived from this software 17 * without specific prior written permission. 18 * 19 * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND 20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 22 * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE 23 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 24 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 25 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 28 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 29 * SUCH DAMAGE. 30 */ 31 32 /*- 33 * Copyright (c) 1998, 2000 The NetBSD Foundation, Inc. 34 * All rights reserved. 35 * 36 * This code is derived from software contributed to The NetBSD Foundation 37 * by Public Access Networks Corporation ("Panix"). It was developed under 38 * contract to Panix by Eric Haszlakiewicz and Thor Lancelot Simon. 39 * 40 * This code is derived from software contributed to The NetBSD Foundation 41 * by Jason R. Thorpe of Zembu Labs, Inc. 42 * 43 * Redistribution and use in source and binary forms, with or without 44 * modification, are permitted provided that the following conditions 45 * are met: 46 * 1. Redistributions of source code must retain the above copyright 47 * notice, this list of conditions and the following disclaimer. 48 * 2. Redistributions in binary form must reproduce the above copyright 49 * notice, this list of conditions and the following disclaimer in the 50 * documentation and/or other materials provided with the distribution. 51 * 52 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 53 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 54 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 55 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 56 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 57 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 58 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 59 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 60 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 61 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 62 * POSSIBILITY OF SUCH DAMAGE. 63 */ 64 65 /* 66 * Copyright (c) 1982, 1986, 1988, 1993 67 * The Regents of the University of California. All rights reserved. 68 * 69 * Redistribution and use in source and binary forms, with or without 70 * modification, are permitted provided that the following conditions 71 * are met: 72 * 1. Redistributions of source code must retain the above copyright 73 * notice, this list of conditions and the following disclaimer. 74 * 2. Redistributions in binary form must reproduce the above copyright 75 * notice, this list of conditions and the following disclaimer in the 76 * documentation and/or other materials provided with the distribution. 77 * 3. Neither the name of the University nor the names of its contributors 78 * may be used to endorse or promote products derived from this software 79 * without specific prior written permission. 80 * 81 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 82 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 83 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 84 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 85 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 86 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 87 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 88 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 89 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 90 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 91 * SUCH DAMAGE. 92 * 93 * @(#)ip_icmp.c 8.2 (Berkeley) 1/4/94 94 */ 95 96 #include <sys/cdefs.h> 97 __KERNEL_RCSID(0, "$NetBSD: ip_icmp.c,v 1.122 2009/12/07 18:47:24 christos Exp $"); 98 99 #include "opt_ipsec.h" 100 101 #include <sys/param.h> 102 #include <sys/systm.h> 103 #include <sys/malloc.h> 104 #include <sys/mbuf.h> 105 #include <sys/protosw.h> 106 #include <sys/socket.h> 107 #include <sys/time.h> 108 #include <sys/kernel.h> 109 #include <sys/syslog.h> 110 #include <sys/sysctl.h> 111 112 #include <net/if.h> 113 #include <net/route.h> 114 115 #include <netinet/in.h> 116 #include <netinet/in_systm.h> 117 #include <netinet/in_var.h> 118 #include <netinet/ip.h> 119 #include <netinet/ip_icmp.h> 120 #include <netinet/ip_var.h> 121 #include <netinet/in_pcb.h> 122 #include <netinet/in_proto.h> 123 #include <netinet/icmp_var.h> 124 #include <netinet/icmp_private.h> 125 126 #ifdef IPSEC 127 #include <netinet6/ipsec.h> 128 #include <netkey/key.h> 129 #endif 130 131 #ifdef FAST_IPSEC 132 #include <netipsec/ipsec.h> 133 #include <netipsec/key.h> 134 #endif /* FAST_IPSEC*/ 135 136 #include <machine/stdarg.h> 137 138 /* 139 * ICMP routines: error generation, receive packet processing, and 140 * routines to turnaround packets back to the originator, and 141 * host table maintenance routines. 142 */ 143 144 int icmpmaskrepl = 0; 145 int icmpbmcastecho = 0; 146 #ifdef ICMPPRINTFS 147 int icmpprintfs = 0; 148 #endif 149 int icmpreturndatabytes = 8; 150 151 percpu_t *icmpstat_percpu; 152 153 /* 154 * List of callbacks to notify when Path MTU changes are made. 155 */ 156 struct icmp_mtudisc_callback { 157 LIST_ENTRY(icmp_mtudisc_callback) mc_list; 158 void (*mc_func)(struct in_addr); 159 }; 160 161 LIST_HEAD(, icmp_mtudisc_callback) icmp_mtudisc_callbacks = 162 LIST_HEAD_INITIALIZER(&icmp_mtudisc_callbacks); 163 164 #if 0 165 static u_int ip_next_mtu(u_int, int); 166 #else 167 /*static*/ u_int ip_next_mtu(u_int, int); 168 #endif 169 170 extern int icmperrppslim; 171 static int icmperrpps_count = 0; 172 static struct timeval icmperrppslim_last; 173 static int icmp_rediraccept = 1; 174 static int icmp_redirtimeout = 600; 175 static struct rttimer_queue *icmp_redirect_timeout_q = NULL; 176 177 static void icmp_mtudisc_timeout(struct rtentry *, struct rttimer *); 178 static void icmp_redirect_timeout(struct rtentry *, struct rttimer *); 179 180 static int icmp_ratelimit(const struct in_addr *, const int, const int); 181 182 static void sysctl_netinet_icmp_setup(struct sysctllog **); 183 184 void 185 icmp_init(void) 186 { 187 188 sysctl_netinet_icmp_setup(NULL); 189 190 /* 191 * This is only useful if the user initializes redirtimeout to 192 * something other than zero. 193 */ 194 if (icmp_redirtimeout != 0) { 195 icmp_redirect_timeout_q = 196 rt_timer_queue_create(icmp_redirtimeout); 197 } 198 199 icmpstat_percpu = percpu_alloc(sizeof(uint64_t) * ICMP_NSTATS); 200 } 201 202 /* 203 * Register a Path MTU Discovery callback. 204 */ 205 void 206 icmp_mtudisc_callback_register(void (*func)(struct in_addr)) 207 { 208 struct icmp_mtudisc_callback *mc; 209 210 for (mc = LIST_FIRST(&icmp_mtudisc_callbacks); mc != NULL; 211 mc = LIST_NEXT(mc, mc_list)) { 212 if (mc->mc_func == func) 213 return; 214 } 215 216 mc = malloc(sizeof(*mc), M_PCB, M_NOWAIT); 217 if (mc == NULL) 218 panic("icmp_mtudisc_callback_register"); 219 220 mc->mc_func = func; 221 LIST_INSERT_HEAD(&icmp_mtudisc_callbacks, mc, mc_list); 222 } 223 224 /* 225 * Generate an error packet of type error 226 * in response to bad packet ip. 227 */ 228 void 229 icmp_error(struct mbuf *n, int type, int code, n_long dest, 230 int destmtu) 231 { 232 struct ip *oip = mtod(n, struct ip *), *nip; 233 unsigned oiplen = oip->ip_hl << 2; 234 struct icmp *icp; 235 struct mbuf *m; 236 struct m_tag *mtag; 237 unsigned icmplen, mblen; 238 239 #ifdef ICMPPRINTFS 240 if (icmpprintfs) 241 printf("icmp_error(%p, type:%d, code:%d)\n", oip, type, code); 242 #endif 243 if (type != ICMP_REDIRECT) 244 ICMP_STATINC(ICMP_STAT_ERROR); 245 /* 246 * Don't send error if the original packet was encrypted. 247 * Don't send error if not the first fragment of message. 248 * Don't error if the old packet protocol was ICMP 249 * error message, only known informational types. 250 */ 251 if (n->m_flags & M_DECRYPTED) 252 goto freeit; 253 if (oip->ip_off &~ htons(IP_MF|IP_DF)) 254 goto freeit; 255 if (oip->ip_p == IPPROTO_ICMP && type != ICMP_REDIRECT && 256 n->m_len >= oiplen + ICMP_MINLEN && 257 !ICMP_INFOTYPE(((struct icmp *)((char *)oip + oiplen))->icmp_type)) { 258 ICMP_STATINC(ICMP_STAT_OLDICMP); 259 goto freeit; 260 } 261 /* Don't send error in response to a multicast or broadcast packet */ 262 if (n->m_flags & (M_BCAST|M_MCAST)) 263 goto freeit; 264 265 /* 266 * First, do a rate limitation check. 267 */ 268 if (icmp_ratelimit(&oip->ip_src, type, code)) { 269 /* XXX stat */ 270 goto freeit; 271 } 272 273 /* 274 * Now, formulate icmp message 275 */ 276 icmplen = oiplen + min(icmpreturndatabytes, 277 ntohs(oip->ip_len) - oiplen); 278 /* 279 * Defend against mbuf chains shorter than oip->ip_len - oiplen: 280 */ 281 mblen = 0; 282 for (m = n; m && (mblen < icmplen); m = m->m_next) 283 mblen += m->m_len; 284 icmplen = min(mblen, icmplen); 285 286 /* 287 * As we are not required to return everything we have, 288 * we return whatever we can return at ease. 289 * 290 * Note that ICMP datagrams longer than 576 octets are out of spec 291 * according to RFC1812; the limit on icmpreturndatabytes below in 292 * icmp_sysctl will keep things below that limit. 293 */ 294 295 KASSERT(ICMP_MINLEN <= MCLBYTES); 296 297 if (icmplen + ICMP_MINLEN > MCLBYTES) 298 icmplen = MCLBYTES - ICMP_MINLEN; 299 300 m = m_gethdr(M_DONTWAIT, MT_HEADER); 301 if (m && (icmplen + ICMP_MINLEN > MHLEN)) { 302 MCLGET(m, M_DONTWAIT); 303 if ((m->m_flags & M_EXT) == 0) { 304 m_freem(m); 305 m = NULL; 306 } 307 } 308 if (m == NULL) 309 goto freeit; 310 MCLAIM(m, n->m_owner); 311 m->m_len = icmplen + ICMP_MINLEN; 312 if ((m->m_flags & M_EXT) == 0) 313 MH_ALIGN(m, m->m_len); 314 icp = mtod(m, struct icmp *); 315 if ((u_int)type > ICMP_MAXTYPE) 316 panic("icmp_error"); 317 ICMP_STATINC(ICMP_STAT_OUTHIST + type); 318 icp->icmp_type = type; 319 if (type == ICMP_REDIRECT) 320 icp->icmp_gwaddr.s_addr = dest; 321 else { 322 icp->icmp_void = 0; 323 /* 324 * The following assignments assume an overlay with the 325 * zeroed icmp_void field. 326 */ 327 if (type == ICMP_PARAMPROB) { 328 icp->icmp_pptr = code; 329 code = 0; 330 } else if (type == ICMP_UNREACH && 331 code == ICMP_UNREACH_NEEDFRAG && destmtu) 332 icp->icmp_nextmtu = htons(destmtu); 333 } 334 335 icp->icmp_code = code; 336 m_copydata(n, 0, icmplen, (void *)&icp->icmp_ip); 337 338 /* 339 * Now, copy old ip header (without options) 340 * in front of icmp message. 341 */ 342 if (m->m_data - sizeof(struct ip) < m->m_pktdat) 343 panic("icmp len"); 344 m->m_data -= sizeof(struct ip); 345 m->m_len += sizeof(struct ip); 346 m->m_pkthdr.len = m->m_len; 347 m->m_pkthdr.rcvif = n->m_pkthdr.rcvif; 348 nip = mtod(m, struct ip *); 349 /* ip_v set in ip_output */ 350 nip->ip_hl = sizeof(struct ip) >> 2; 351 nip->ip_tos = 0; 352 nip->ip_len = htons(m->m_len); 353 /* ip_id set in ip_output */ 354 nip->ip_off = htons(0); 355 /* ip_ttl set in icmp_reflect */ 356 nip->ip_p = IPPROTO_ICMP; 357 nip->ip_src = oip->ip_src; 358 nip->ip_dst = oip->ip_dst; 359 /* move PF m_tag to new packet, if it exists */ 360 mtag = m_tag_find(n, PACKET_TAG_PF, NULL); 361 if (mtag != NULL) { 362 m_tag_unlink(n, mtag); 363 m_tag_prepend(m, mtag); 364 } 365 icmp_reflect(m); 366 367 freeit: 368 m_freem(n); 369 } 370 371 struct sockaddr_in icmpsrc = { 372 .sin_len = sizeof (struct sockaddr_in), 373 .sin_family = AF_INET, 374 }; 375 static struct sockaddr_in icmpdst = { 376 .sin_len = sizeof (struct sockaddr_in), 377 .sin_family = AF_INET, 378 }; 379 static struct sockaddr_in icmpgw = { 380 .sin_len = sizeof (struct sockaddr_in), 381 .sin_family = AF_INET, 382 }; 383 struct sockaddr_in icmpmask = { 384 .sin_len = 8, 385 .sin_family = 0, 386 }; 387 388 /* 389 * Process a received ICMP message. 390 */ 391 void 392 icmp_input(struct mbuf *m, ...) 393 { 394 int proto; 395 struct icmp *icp; 396 struct ip *ip = mtod(m, struct ip *); 397 int icmplen; 398 int i; 399 struct in_ifaddr *ia; 400 void *(*ctlfunc)(int, const struct sockaddr *, void *); 401 int code; 402 int hlen; 403 va_list ap; 404 struct rtentry *rt; 405 406 va_start(ap, m); 407 hlen = va_arg(ap, int); 408 proto = va_arg(ap, int); 409 va_end(ap); 410 411 /* 412 * Locate icmp structure in mbuf, and check 413 * that not corrupted and of at least minimum length. 414 */ 415 icmplen = ntohs(ip->ip_len) - hlen; 416 #ifdef ICMPPRINTFS 417 if (icmpprintfs) { 418 printf("icmp_input from `%s' to ", inet_ntoa(ip->ip_src)); 419 printf("`%s', len %d\n", inet_ntoa(ip->ip_dst), icmplen); 420 } 421 #endif 422 if (icmplen < ICMP_MINLEN) { 423 ICMP_STATINC(ICMP_STAT_TOOSHORT); 424 goto freeit; 425 } 426 i = hlen + min(icmplen, ICMP_ADVLENMIN); 427 if ((m->m_len < i || M_READONLY(m)) && (m = m_pullup(m, i)) == 0) { 428 ICMP_STATINC(ICMP_STAT_TOOSHORT); 429 return; 430 } 431 ip = mtod(m, struct ip *); 432 m->m_len -= hlen; 433 m->m_data += hlen; 434 icp = mtod(m, struct icmp *); 435 /* Don't need to assert alignment, here. */ 436 if (in_cksum(m, icmplen)) { 437 ICMP_STATINC(ICMP_STAT_CHECKSUM); 438 goto freeit; 439 } 440 m->m_len += hlen; 441 m->m_data -= hlen; 442 443 #ifdef ICMPPRINTFS 444 /* 445 * Message type specific processing. 446 */ 447 if (icmpprintfs) 448 printf("icmp_input(type:%d, code:%d)\n", icp->icmp_type, 449 icp->icmp_code); 450 #endif 451 if (icp->icmp_type > ICMP_MAXTYPE) 452 goto raw; 453 ICMP_STATINC(ICMP_STAT_INHIST + icp->icmp_type); 454 code = icp->icmp_code; 455 switch (icp->icmp_type) { 456 457 case ICMP_UNREACH: 458 switch (code) { 459 case ICMP_UNREACH_NET: 460 code = PRC_UNREACH_NET; 461 break; 462 463 case ICMP_UNREACH_HOST: 464 code = PRC_UNREACH_HOST; 465 break; 466 467 case ICMP_UNREACH_PROTOCOL: 468 code = PRC_UNREACH_PROTOCOL; 469 break; 470 471 case ICMP_UNREACH_PORT: 472 code = PRC_UNREACH_PORT; 473 break; 474 475 case ICMP_UNREACH_SRCFAIL: 476 code = PRC_UNREACH_SRCFAIL; 477 break; 478 479 case ICMP_UNREACH_NEEDFRAG: 480 code = PRC_MSGSIZE; 481 break; 482 483 case ICMP_UNREACH_NET_UNKNOWN: 484 case ICMP_UNREACH_NET_PROHIB: 485 case ICMP_UNREACH_TOSNET: 486 code = PRC_UNREACH_NET; 487 break; 488 489 case ICMP_UNREACH_HOST_UNKNOWN: 490 case ICMP_UNREACH_ISOLATED: 491 case ICMP_UNREACH_HOST_PROHIB: 492 case ICMP_UNREACH_TOSHOST: 493 code = PRC_UNREACH_HOST; 494 break; 495 496 default: 497 goto badcode; 498 } 499 goto deliver; 500 501 case ICMP_TIMXCEED: 502 if (code > 1) 503 goto badcode; 504 code += PRC_TIMXCEED_INTRANS; 505 goto deliver; 506 507 case ICMP_PARAMPROB: 508 if (code > 1) 509 goto badcode; 510 code = PRC_PARAMPROB; 511 goto deliver; 512 513 case ICMP_SOURCEQUENCH: 514 if (code) 515 goto badcode; 516 code = PRC_QUENCH; 517 goto deliver; 518 519 deliver: 520 /* 521 * Problem with datagram; advise higher level routines. 522 */ 523 if (icmplen < ICMP_ADVLENMIN || icmplen < ICMP_ADVLEN(icp) || 524 icp->icmp_ip.ip_hl < (sizeof(struct ip) >> 2)) { 525 ICMP_STATINC(ICMP_STAT_BADLEN); 526 goto freeit; 527 } 528 if (IN_MULTICAST(icp->icmp_ip.ip_dst.s_addr)) 529 goto badcode; 530 #ifdef ICMPPRINTFS 531 if (icmpprintfs) 532 printf("deliver to protocol %d\n", icp->icmp_ip.ip_p); 533 #endif 534 icmpsrc.sin_addr = icp->icmp_ip.ip_dst; 535 ctlfunc = inetsw[ip_protox[icp->icmp_ip.ip_p]].pr_ctlinput; 536 if (ctlfunc) 537 (void) (*ctlfunc)(code, sintosa(&icmpsrc), 538 &icp->icmp_ip); 539 break; 540 541 badcode: 542 ICMP_STATINC(ICMP_STAT_BADCODE); 543 break; 544 545 case ICMP_ECHO: 546 if (!icmpbmcastecho && 547 (m->m_flags & (M_MCAST | M_BCAST)) != 0) { 548 ICMP_STATINC(ICMP_STAT_BMCASTECHO); 549 break; 550 } 551 icp->icmp_type = ICMP_ECHOREPLY; 552 goto reflect; 553 554 case ICMP_TSTAMP: 555 if (icmplen < ICMP_TSLEN) { 556 ICMP_STATINC(ICMP_STAT_BADLEN); 557 break; 558 } 559 if (!icmpbmcastecho && 560 (m->m_flags & (M_MCAST | M_BCAST)) != 0) { 561 ICMP_STATINC(ICMP_STAT_BMCASTTSTAMP); 562 break; 563 } 564 icp->icmp_type = ICMP_TSTAMPREPLY; 565 icp->icmp_rtime = iptime(); 566 icp->icmp_ttime = icp->icmp_rtime; /* bogus, do later! */ 567 goto reflect; 568 569 case ICMP_MASKREQ: 570 if (icmpmaskrepl == 0) 571 break; 572 /* 573 * We are not able to respond with all ones broadcast 574 * unless we receive it over a point-to-point interface. 575 */ 576 if (icmplen < ICMP_MASKLEN) { 577 ICMP_STATINC(ICMP_STAT_BADLEN); 578 break; 579 } 580 if (ip->ip_dst.s_addr == INADDR_BROADCAST || 581 in_nullhost(ip->ip_dst)) 582 icmpdst.sin_addr = ip->ip_src; 583 else 584 icmpdst.sin_addr = ip->ip_dst; 585 ia = ifatoia(ifaof_ifpforaddr(sintosa(&icmpdst), 586 m->m_pkthdr.rcvif)); 587 if (ia == 0) 588 break; 589 icp->icmp_type = ICMP_MASKREPLY; 590 icp->icmp_mask = ia->ia_sockmask.sin_addr.s_addr; 591 if (in_nullhost(ip->ip_src)) { 592 if (ia->ia_ifp->if_flags & IFF_BROADCAST) 593 ip->ip_src = ia->ia_broadaddr.sin_addr; 594 else if (ia->ia_ifp->if_flags & IFF_POINTOPOINT) 595 ip->ip_src = ia->ia_dstaddr.sin_addr; 596 } 597 reflect: 598 { 599 uint64_t *icps = percpu_getref(icmpstat_percpu); 600 icps[ICMP_STAT_REFLECT]++; 601 icps[ICMP_STAT_OUTHIST + icp->icmp_type]++; 602 percpu_putref(icmpstat_percpu); 603 } 604 icmp_reflect(m); 605 return; 606 607 case ICMP_REDIRECT: 608 if (code > 3) 609 goto badcode; 610 if (icmp_rediraccept == 0) 611 goto freeit; 612 if (icmplen < ICMP_ADVLENMIN || icmplen < ICMP_ADVLEN(icp) || 613 icp->icmp_ip.ip_hl < (sizeof(struct ip) >> 2)) { 614 ICMP_STATINC(ICMP_STAT_BADLEN); 615 break; 616 } 617 /* 618 * Short circuit routing redirects to force 619 * immediate change in the kernel's routing 620 * tables. The message is also handed to anyone 621 * listening on a raw socket (e.g. the routing 622 * daemon for use in updating its tables). 623 */ 624 icmpgw.sin_addr = ip->ip_src; 625 icmpdst.sin_addr = icp->icmp_gwaddr; 626 #ifdef ICMPPRINTFS 627 if (icmpprintfs) { 628 printf("redirect dst `%s' to `%s'\n", 629 inet_ntoa(icp->icmp_ip.ip_dst), 630 inet_ntoa(icp->icmp_gwaddr)); 631 } 632 #endif 633 icmpsrc.sin_addr = icp->icmp_ip.ip_dst; 634 rt = NULL; 635 rtredirect(sintosa(&icmpsrc), sintosa(&icmpdst), 636 NULL, RTF_GATEWAY | RTF_HOST, sintosa(&icmpgw), &rt); 637 if (rt != NULL && icmp_redirtimeout != 0) { 638 i = rt_timer_add(rt, icmp_redirect_timeout, 639 icmp_redirect_timeout_q); 640 if (i) 641 log(LOG_ERR, "ICMP: redirect failed to " 642 "register timeout for route to %x, " 643 "code %d\n", 644 icp->icmp_ip.ip_dst.s_addr, i); 645 } 646 if (rt != NULL) 647 rtfree(rt); 648 649 pfctlinput(PRC_REDIRECT_HOST, sintosa(&icmpsrc)); 650 #if defined(IPSEC) || defined(FAST_IPSEC) 651 key_sa_routechange((struct sockaddr *)&icmpsrc); 652 #endif 653 break; 654 655 /* 656 * No kernel processing for the following; 657 * just fall through to send to raw listener. 658 */ 659 case ICMP_ECHOREPLY: 660 case ICMP_ROUTERADVERT: 661 case ICMP_ROUTERSOLICIT: 662 case ICMP_TSTAMPREPLY: 663 case ICMP_IREQREPLY: 664 case ICMP_MASKREPLY: 665 default: 666 break; 667 } 668 669 raw: 670 rip_input(m, hlen, proto); 671 return; 672 673 freeit: 674 m_freem(m); 675 return; 676 } 677 678 /* 679 * Reflect the ip packet back to the source 680 */ 681 void 682 icmp_reflect(struct mbuf *m) 683 { 684 struct ip *ip = mtod(m, struct ip *); 685 struct in_ifaddr *ia; 686 struct ifaddr *ifa; 687 struct sockaddr_in *sin = 0; 688 struct in_addr t; 689 struct mbuf *opts = 0; 690 int optlen = (ip->ip_hl << 2) - sizeof(struct ip); 691 692 if (!in_canforward(ip->ip_src) && 693 ((ip->ip_src.s_addr & IN_CLASSA_NET) != 694 htonl(IN_LOOPBACKNET << IN_CLASSA_NSHIFT))) { 695 m_freem(m); /* Bad return address */ 696 goto done; /* ip_output() will check for broadcast */ 697 } 698 t = ip->ip_dst; 699 ip->ip_dst = ip->ip_src; 700 /* 701 * If the incoming packet was addressed directly to us, use 702 * dst as the src for the reply. Otherwise (broadcast or 703 * anonymous), use an address which corresponds to the 704 * incoming interface, with a preference for the address which 705 * corresponds to the route to the destination of the ICMP. 706 */ 707 708 /* Look for packet addressed to us */ 709 INADDR_TO_IA(t, ia); 710 711 /* look for packet sent to broadcast address */ 712 if (ia == NULL && m->m_pkthdr.rcvif && 713 (m->m_pkthdr.rcvif->if_flags & IFF_BROADCAST)) { 714 IFADDR_FOREACH(ifa, m->m_pkthdr.rcvif) { 715 if (ifa->ifa_addr->sa_family != AF_INET) 716 continue; 717 if (in_hosteq(t,ifatoia(ifa)->ia_broadaddr.sin_addr)) { 718 ia = ifatoia(ifa); 719 break; 720 } 721 } 722 } 723 724 if (ia) 725 sin = &ia->ia_addr; 726 727 icmpdst.sin_addr = t; 728 729 /* 730 * if the packet is addressed somewhere else, compute the 731 * source address for packets routed back to the source, and 732 * use that, if it's an address on the interface which 733 * received the packet 734 */ 735 if (sin == NULL && m->m_pkthdr.rcvif) { 736 struct sockaddr_in sin_dst; 737 struct route icmproute; 738 int errornum; 739 740 sockaddr_in_init(&sin_dst, &ip->ip_dst, 0); 741 memset(&icmproute, 0, sizeof(icmproute)); 742 errornum = 0; 743 sin = in_selectsrc(&sin_dst, &icmproute, 0, NULL, &errornum); 744 /* errornum is never used */ 745 rtcache_free(&icmproute); 746 /* check to make sure sin is a source address on rcvif */ 747 if (sin) { 748 t = sin->sin_addr; 749 sin = NULL; 750 INADDR_TO_IA(t, ia); 751 while (ia) { 752 if (ia->ia_ifp == m->m_pkthdr.rcvif) { 753 sin = &ia->ia_addr; 754 break; 755 } 756 NEXT_IA_WITH_SAME_ADDR(ia); 757 } 758 } 759 } 760 761 /* 762 * if it was not addressed to us, but the route doesn't go out 763 * the source interface, pick an address on the source 764 * interface. This can happen when routing is asymmetric, or 765 * when the incoming packet was encapsulated 766 */ 767 if (sin == NULL && m->m_pkthdr.rcvif) { 768 IFADDR_FOREACH(ifa, m->m_pkthdr.rcvif) { 769 if (ifa->ifa_addr->sa_family != AF_INET) 770 continue; 771 sin = &(ifatoia(ifa)->ia_addr); 772 break; 773 } 774 } 775 776 /* 777 * The following happens if the packet was not addressed to us, 778 * and was received on an interface with no IP address: 779 * We find the first AF_INET address on the first non-loopback 780 * interface. 781 */ 782 if (sin == NULL) 783 TAILQ_FOREACH(ia, &in_ifaddrhead, ia_list) { 784 if (ia->ia_ifp->if_flags & IFF_LOOPBACK) 785 continue; 786 sin = &ia->ia_addr; 787 break; 788 } 789 790 /* 791 * If we still didn't find an address, punt. We could have an 792 * interface up (and receiving packets) with no address. 793 */ 794 if (sin == NULL) { 795 m_freem(m); 796 goto done; 797 } 798 799 ip->ip_src = sin->sin_addr; 800 ip->ip_ttl = MAXTTL; 801 802 if (optlen > 0) { 803 u_char *cp; 804 int opt, cnt; 805 u_int len; 806 807 /* 808 * Retrieve any source routing from the incoming packet; 809 * add on any record-route or timestamp options. 810 */ 811 cp = (u_char *) (ip + 1); 812 if ((opts = ip_srcroute()) == 0 && 813 (opts = m_gethdr(M_DONTWAIT, MT_HEADER))) { 814 MCLAIM(opts, m->m_owner); 815 opts->m_len = sizeof(struct in_addr); 816 *mtod(opts, struct in_addr *) = zeroin_addr; 817 } 818 if (opts) { 819 #ifdef ICMPPRINTFS 820 if (icmpprintfs) 821 printf("icmp_reflect optlen %d rt %d => ", 822 optlen, opts->m_len); 823 #endif 824 for (cnt = optlen; cnt > 0; cnt -= len, cp += len) { 825 opt = cp[IPOPT_OPTVAL]; 826 if (opt == IPOPT_EOL) 827 break; 828 if (opt == IPOPT_NOP) 829 len = 1; 830 else { 831 if (cnt < IPOPT_OLEN + sizeof(*cp)) 832 break; 833 len = cp[IPOPT_OLEN]; 834 if (len < IPOPT_OLEN + sizeof(*cp) || 835 len > cnt) 836 break; 837 } 838 /* 839 * Should check for overflow, but it "can't happen" 840 */ 841 if (opt == IPOPT_RR || opt == IPOPT_TS || 842 opt == IPOPT_SECURITY) { 843 memmove(mtod(opts, char *) + opts->m_len, 844 cp, len); 845 opts->m_len += len; 846 } 847 } 848 /* Terminate & pad, if necessary */ 849 if ((cnt = opts->m_len % 4) != 0) { 850 for (; cnt < 4; cnt++) { 851 *(mtod(opts, char *) + opts->m_len) = 852 IPOPT_EOL; 853 opts->m_len++; 854 } 855 } 856 #ifdef ICMPPRINTFS 857 if (icmpprintfs) 858 printf("%d\n", opts->m_len); 859 #endif 860 } 861 /* 862 * Now strip out original options by copying rest of first 863 * mbuf's data back, and adjust the IP length. 864 */ 865 ip->ip_len = htons(ntohs(ip->ip_len) - optlen); 866 ip->ip_hl = sizeof(struct ip) >> 2; 867 m->m_len -= optlen; 868 if (m->m_flags & M_PKTHDR) 869 m->m_pkthdr.len -= optlen; 870 optlen += sizeof(struct ip); 871 memmove(ip + 1, (char *)ip + optlen, 872 (unsigned)(m->m_len - sizeof(struct ip))); 873 } 874 m_tag_delete_nonpersistent(m); 875 m->m_flags &= ~(M_BCAST|M_MCAST); 876 877 /* 878 * Clear any in-bound checksum flags for this packet. 879 */ 880 if (m->m_flags & M_PKTHDR) 881 m->m_pkthdr.csum_flags = 0; 882 883 icmp_send(m, opts); 884 done: 885 if (opts) 886 (void)m_free(opts); 887 } 888 889 /* 890 * Send an icmp packet back to the ip level, 891 * after supplying a checksum. 892 */ 893 void 894 icmp_send(struct mbuf *m, struct mbuf *opts) 895 { 896 struct ip *ip = mtod(m, struct ip *); 897 int hlen; 898 struct icmp *icp; 899 900 hlen = ip->ip_hl << 2; 901 m->m_data += hlen; 902 m->m_len -= hlen; 903 icp = mtod(m, struct icmp *); 904 icp->icmp_cksum = 0; 905 icp->icmp_cksum = in_cksum(m, ntohs(ip->ip_len) - hlen); 906 m->m_data -= hlen; 907 m->m_len += hlen; 908 #ifdef ICMPPRINTFS 909 if (icmpprintfs) { 910 printf("icmp_send to destination `%s' from `%s'\n", 911 inet_ntoa(ip->ip_dst), inet_ntoa(ip->ip_src)); 912 } 913 #endif 914 (void)ip_output(m, opts, NULL, 0, NULL, NULL); 915 } 916 917 n_time 918 iptime(void) 919 { 920 struct timeval atv; 921 u_long t; 922 923 microtime(&atv); 924 t = (atv.tv_sec % (24*60*60)) * 1000 + atv.tv_usec / 1000; 925 return (htonl(t)); 926 } 927 928 /* 929 * sysctl helper routine for net.inet.icmp.returndatabytes. ensures 930 * that the new value is in the correct range. 931 */ 932 static int 933 sysctl_net_inet_icmp_returndatabytes(SYSCTLFN_ARGS) 934 { 935 int error, t; 936 struct sysctlnode node; 937 938 node = *rnode; 939 node.sysctl_data = &t; 940 t = icmpreturndatabytes; 941 error = sysctl_lookup(SYSCTLFN_CALL(&node)); 942 if (error || newp == NULL) 943 return (error); 944 945 if (t < 8 || t > 512) 946 return (EINVAL); 947 icmpreturndatabytes = t; 948 949 return (0); 950 } 951 952 /* 953 * sysctl helper routine for net.inet.icmp.redirtimeout. ensures that 954 * the given value is not less than zero and then resets the timeout 955 * queue. 956 */ 957 static int 958 sysctl_net_inet_icmp_redirtimeout(SYSCTLFN_ARGS) 959 { 960 int error, tmp; 961 struct sysctlnode node; 962 963 node = *rnode; 964 node.sysctl_data = &tmp; 965 tmp = icmp_redirtimeout; 966 error = sysctl_lookup(SYSCTLFN_CALL(&node)); 967 if (error || newp == NULL) 968 return (error); 969 if (tmp < 0) 970 return (EINVAL); 971 icmp_redirtimeout = tmp; 972 973 /* 974 * was it a *defined* side-effect that anyone even *reading* 975 * this value causes these things to happen? 976 */ 977 if (icmp_redirect_timeout_q != NULL) { 978 if (icmp_redirtimeout == 0) { 979 rt_timer_queue_destroy(icmp_redirect_timeout_q, 980 true); 981 icmp_redirect_timeout_q = NULL; 982 } else { 983 rt_timer_queue_change(icmp_redirect_timeout_q, 984 icmp_redirtimeout); 985 } 986 } else if (icmp_redirtimeout > 0) { 987 icmp_redirect_timeout_q = 988 rt_timer_queue_create(icmp_redirtimeout); 989 } 990 991 return (0); 992 } 993 994 static int 995 sysctl_net_inet_icmp_stats(SYSCTLFN_ARGS) 996 { 997 998 return (NETSTAT_SYSCTL(icmpstat_percpu, ICMP_NSTATS)); 999 } 1000 1001 static void 1002 sysctl_netinet_icmp_setup(struct sysctllog **clog) 1003 { 1004 1005 sysctl_createv(clog, 0, NULL, NULL, 1006 CTLFLAG_PERMANENT, 1007 CTLTYPE_NODE, "net", NULL, 1008 NULL, 0, NULL, 0, 1009 CTL_NET, CTL_EOL); 1010 sysctl_createv(clog, 0, NULL, NULL, 1011 CTLFLAG_PERMANENT, 1012 CTLTYPE_NODE, "inet", NULL, 1013 NULL, 0, NULL, 0, 1014 CTL_NET, PF_INET, CTL_EOL); 1015 sysctl_createv(clog, 0, NULL, NULL, 1016 CTLFLAG_PERMANENT, 1017 CTLTYPE_NODE, "icmp", 1018 SYSCTL_DESCR("ICMPv4 related settings"), 1019 NULL, 0, NULL, 0, 1020 CTL_NET, PF_INET, IPPROTO_ICMP, CTL_EOL); 1021 1022 sysctl_createv(clog, 0, NULL, NULL, 1023 CTLFLAG_PERMANENT|CTLFLAG_READWRITE, 1024 CTLTYPE_INT, "maskrepl", 1025 SYSCTL_DESCR("Respond to ICMP_MASKREQ messages"), 1026 NULL, 0, &icmpmaskrepl, 0, 1027 CTL_NET, PF_INET, IPPROTO_ICMP, 1028 ICMPCTL_MASKREPL, CTL_EOL); 1029 sysctl_createv(clog, 0, NULL, NULL, 1030 CTLFLAG_PERMANENT|CTLFLAG_READWRITE, 1031 CTLTYPE_INT, "returndatabytes", 1032 SYSCTL_DESCR("Number of bytes to return in an ICMP " 1033 "error message"), 1034 sysctl_net_inet_icmp_returndatabytes, 0, 1035 &icmpreturndatabytes, 0, 1036 CTL_NET, PF_INET, IPPROTO_ICMP, 1037 ICMPCTL_RETURNDATABYTES, CTL_EOL); 1038 sysctl_createv(clog, 0, NULL, NULL, 1039 CTLFLAG_PERMANENT|CTLFLAG_READWRITE, 1040 CTLTYPE_INT, "errppslimit", 1041 SYSCTL_DESCR("Maximum number of outgoing ICMP error " 1042 "messages per second"), 1043 NULL, 0, &icmperrppslim, 0, 1044 CTL_NET, PF_INET, IPPROTO_ICMP, 1045 ICMPCTL_ERRPPSLIMIT, CTL_EOL); 1046 sysctl_createv(clog, 0, NULL, NULL, 1047 CTLFLAG_PERMANENT|CTLFLAG_READWRITE, 1048 CTLTYPE_INT, "rediraccept", 1049 SYSCTL_DESCR("Accept ICMP_REDIRECT messages"), 1050 NULL, 0, &icmp_rediraccept, 0, 1051 CTL_NET, PF_INET, IPPROTO_ICMP, 1052 ICMPCTL_REDIRACCEPT, CTL_EOL); 1053 sysctl_createv(clog, 0, NULL, NULL, 1054 CTLFLAG_PERMANENT|CTLFLAG_READWRITE, 1055 CTLTYPE_INT, "redirtimeout", 1056 SYSCTL_DESCR("Lifetime of ICMP_REDIRECT generated " 1057 "routes"), 1058 sysctl_net_inet_icmp_redirtimeout, 0, 1059 &icmp_redirtimeout, 0, 1060 CTL_NET, PF_INET, IPPROTO_ICMP, 1061 ICMPCTL_REDIRTIMEOUT, CTL_EOL); 1062 sysctl_createv(clog, 0, NULL, NULL, 1063 CTLFLAG_PERMANENT, 1064 CTLTYPE_STRUCT, "stats", 1065 SYSCTL_DESCR("ICMP statistics"), 1066 sysctl_net_inet_icmp_stats, 0, NULL, 0, 1067 CTL_NET, PF_INET, IPPROTO_ICMP, ICMPCTL_STATS, 1068 CTL_EOL); 1069 sysctl_createv(clog, 0, NULL, NULL, 1070 CTLFLAG_PERMANENT|CTLFLAG_READWRITE, 1071 CTLTYPE_INT, "bmcastecho", 1072 SYSCTL_DESCR("Respond to ICMP_ECHO or ICMP_TIMESTAMP " 1073 "message to the broadcast or multicast"), 1074 NULL, 0, &icmpbmcastecho, 0, 1075 CTL_NET, PF_INET, IPPROTO_ICMP, ICMPCTL_BMCASTECHO, 1076 CTL_EOL); 1077 } 1078 1079 void 1080 icmp_statinc(u_int stat) 1081 { 1082 1083 KASSERT(stat < ICMP_NSTATS); 1084 ICMP_STATINC(stat); 1085 } 1086 1087 /* Table of common MTUs: */ 1088 1089 static const u_int mtu_table[] = { 1090 65535, 65280, 32000, 17914, 9180, 8166, 1091 4352, 2002, 1492, 1006, 508, 296, 68, 0 1092 }; 1093 1094 void 1095 icmp_mtudisc(struct icmp *icp, struct in_addr faddr) 1096 { 1097 struct icmp_mtudisc_callback *mc; 1098 struct sockaddr *dst = sintosa(&icmpsrc); 1099 struct rtentry *rt; 1100 u_long mtu = ntohs(icp->icmp_nextmtu); /* Why a long? IPv6 */ 1101 int error; 1102 1103 rt = rtalloc1(dst, 1); 1104 if (rt == 0) 1105 return; 1106 1107 /* If we didn't get a host route, allocate one */ 1108 1109 if ((rt->rt_flags & RTF_HOST) == 0) { 1110 struct rtentry *nrt; 1111 1112 error = rtrequest((int) RTM_ADD, dst, 1113 (struct sockaddr *) rt->rt_gateway, 1114 (struct sockaddr *) 0, 1115 RTF_GATEWAY | RTF_HOST | RTF_DYNAMIC, &nrt); 1116 if (error) { 1117 rtfree(rt); 1118 return; 1119 } 1120 nrt->rt_rmx = rt->rt_rmx; 1121 rtfree(rt); 1122 rt = nrt; 1123 } 1124 error = rt_timer_add(rt, icmp_mtudisc_timeout, ip_mtudisc_timeout_q); 1125 if (error) { 1126 rtfree(rt); 1127 return; 1128 } 1129 1130 if (mtu == 0) { 1131 int i = 0; 1132 1133 mtu = ntohs(icp->icmp_ip.ip_len); 1134 /* Some 4.2BSD-based routers incorrectly adjust the ip_len */ 1135 if (mtu > rt->rt_rmx.rmx_mtu && rt->rt_rmx.rmx_mtu != 0) 1136 mtu -= (icp->icmp_ip.ip_hl << 2); 1137 1138 /* If we still can't guess a value, try the route */ 1139 1140 if (mtu == 0) { 1141 mtu = rt->rt_rmx.rmx_mtu; 1142 1143 /* If no route mtu, default to the interface mtu */ 1144 1145 if (mtu == 0) 1146 mtu = rt->rt_ifp->if_mtu; 1147 } 1148 1149 for (i = 0; i < sizeof(mtu_table) / sizeof(mtu_table[0]); i++) 1150 if (mtu > mtu_table[i]) { 1151 mtu = mtu_table[i]; 1152 break; 1153 } 1154 } 1155 1156 /* 1157 * XXX: RTV_MTU is overloaded, since the admin can set it 1158 * to turn off PMTU for a route, and the kernel can 1159 * set it to indicate a serious problem with PMTU 1160 * on a route. We should be using a separate flag 1161 * for the kernel to indicate this. 1162 */ 1163 1164 if ((rt->rt_rmx.rmx_locks & RTV_MTU) == 0) { 1165 if (mtu < 296 || mtu > rt->rt_ifp->if_mtu) 1166 rt->rt_rmx.rmx_locks |= RTV_MTU; 1167 else if (rt->rt_rmx.rmx_mtu > mtu || 1168 rt->rt_rmx.rmx_mtu == 0) { 1169 ICMP_STATINC(ICMP_STAT_PMTUCHG); 1170 rt->rt_rmx.rmx_mtu = mtu; 1171 } 1172 } 1173 1174 if (rt) 1175 rtfree(rt); 1176 1177 /* 1178 * Notify protocols that the MTU for this destination 1179 * has changed. 1180 */ 1181 for (mc = LIST_FIRST(&icmp_mtudisc_callbacks); mc != NULL; 1182 mc = LIST_NEXT(mc, mc_list)) 1183 (*mc->mc_func)(faddr); 1184 } 1185 1186 /* 1187 * Return the next larger or smaller MTU plateau (table from RFC 1191) 1188 * given current value MTU. If DIR is less than zero, a larger plateau 1189 * is returned; otherwise, a smaller value is returned. 1190 */ 1191 u_int 1192 ip_next_mtu(u_int mtu, int dir) /* XXX */ 1193 { 1194 int i; 1195 1196 for (i = 0; i < (sizeof mtu_table) / (sizeof mtu_table[0]); i++) { 1197 if (mtu >= mtu_table[i]) 1198 break; 1199 } 1200 1201 if (dir < 0) { 1202 if (i == 0) { 1203 return 0; 1204 } else { 1205 return mtu_table[i - 1]; 1206 } 1207 } else { 1208 if (mtu_table[i] == 0) { 1209 return 0; 1210 } else if (mtu > mtu_table[i]) { 1211 return mtu_table[i]; 1212 } else { 1213 return mtu_table[i + 1]; 1214 } 1215 } 1216 } 1217 1218 static void 1219 icmp_mtudisc_timeout(struct rtentry *rt, struct rttimer *r) 1220 { 1221 if (rt == NULL) 1222 panic("icmp_mtudisc_timeout: bad route to timeout"); 1223 if ((rt->rt_flags & (RTF_DYNAMIC | RTF_HOST)) == 1224 (RTF_DYNAMIC | RTF_HOST)) { 1225 rtrequest((int) RTM_DELETE, rt_getkey(rt), 1226 rt->rt_gateway, rt_mask(rt), rt->rt_flags, 0); 1227 } else { 1228 if ((rt->rt_rmx.rmx_locks & RTV_MTU) == 0) { 1229 rt->rt_rmx.rmx_mtu = 0; 1230 } 1231 } 1232 } 1233 1234 static void 1235 icmp_redirect_timeout(struct rtentry *rt, struct rttimer *r) 1236 { 1237 if (rt == NULL) 1238 panic("icmp_redirect_timeout: bad route to timeout"); 1239 if ((rt->rt_flags & (RTF_DYNAMIC | RTF_HOST)) == 1240 (RTF_DYNAMIC | RTF_HOST)) { 1241 rtrequest((int) RTM_DELETE, rt_getkey(rt), 1242 rt->rt_gateway, rt_mask(rt), rt->rt_flags, 0); 1243 } 1244 } 1245 1246 /* 1247 * Perform rate limit check. 1248 * Returns 0 if it is okay to send the icmp packet. 1249 * Returns 1 if the router SHOULD NOT send this icmp packet due to rate 1250 * limitation. 1251 * 1252 * XXX per-destination/type check necessary? 1253 */ 1254 static int 1255 icmp_ratelimit(const struct in_addr *dst, const int type, 1256 const int code) 1257 { 1258 1259 /* PPS limit */ 1260 if (!ppsratecheck(&icmperrppslim_last, &icmperrpps_count, 1261 icmperrppslim)) { 1262 /* The packet is subject to rate limit */ 1263 return 1; 1264 } 1265 1266 /* okay to send */ 1267 return 0; 1268 } 1269