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