Home | History | Annotate | Line # | Download | only in netinet
ip_icmp.c revision 1.47
      1 /*	$NetBSD: ip_icmp.c,v 1.47 2000/06/10 12:39:19 darrenr 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 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  * Redistribution and use in source and binary forms, with or without
     41  * modification, are permitted provided that the following conditions
     42  * are met:
     43  * 1. Redistributions of source code must retain the above copyright
     44  *    notice, this list of conditions and the following disclaimer.
     45  * 2. Redistributions in binary form must reproduce the above copyright
     46  *    notice, this list of conditions and the following disclaimer in the
     47  *    documentation and/or other materials provided with the distribution.
     48  * 3. All advertising materials mentioning features or use of this software
     49  *    must display the following acknowledgement:
     50  *	This product includes software developed by the NetBSD
     51  *	Foundation, Inc. and its contributors.
     52  * 4. Neither the name of The NetBSD Foundation nor the names of its
     53  *    contributors may be used to endorse or promote products derived
     54  *    from this software without specific prior written permission.
     55  *
     56  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
     57  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
     58  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
     59  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
     60  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
     61  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
     62  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
     63  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
     64  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
     65  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
     66  * POSSIBILITY OF SUCH DAMAGE.
     67  */
     68 
     69 /*
     70  * Copyright (c) 1982, 1986, 1988, 1993
     71  *	The Regents of the University of California.  All rights reserved.
     72  *
     73  * Redistribution and use in source and binary forms, with or without
     74  * modification, are permitted provided that the following conditions
     75  * are met:
     76  * 1. Redistributions of source code must retain the above copyright
     77  *    notice, this list of conditions and the following disclaimer.
     78  * 2. Redistributions in binary form must reproduce the above copyright
     79  *    notice, this list of conditions and the following disclaimer in the
     80  *    documentation and/or other materials provided with the distribution.
     81  * 3. All advertising materials mentioning features or use of this software
     82  *    must display the following acknowledgement:
     83  *	This product includes software developed by the University of
     84  *	California, Berkeley and its contributors.
     85  * 4. Neither the name of the University nor the names of its contributors
     86  *    may be used to endorse or promote products derived from this software
     87  *    without specific prior written permission.
     88  *
     89  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
     90  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
     91  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
     92  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
     93  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
     94  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
     95  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
     96  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
     97  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
     98  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
     99  * SUCH DAMAGE.
    100  *
    101  *	@(#)ip_icmp.c	8.2 (Berkeley) 1/4/94
    102  */
    103 
    104 #include "opt_ipsec.h"
    105 
    106 #include <sys/param.h>
    107 #include <sys/systm.h>
    108 #include <sys/malloc.h>
    109 #include <sys/mbuf.h>
    110 #include <sys/protosw.h>
    111 #include <sys/socket.h>
    112 #include <sys/time.h>
    113 #include <sys/kernel.h>
    114 #include <sys/proc.h>
    115 
    116 #include <vm/vm.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/icmp_var.h>
    130 
    131 #ifdef IPSEC
    132 #include <netinet6/ipsec.h>
    133 #include <netkey/key.h>
    134 #include <netkey/key_debug.h>
    135 #endif
    136 
    137 #include <machine/stdarg.h>
    138 
    139 /*
    140  * ICMP routines: error generation, receive packet processing, and
    141  * routines to turnaround packets back to the originator, and
    142  * host table maintenance routines.
    143  */
    144 
    145 int	icmpmaskrepl = 0;
    146 #ifdef ICMPPRINTFS
    147 int	icmpprintfs = 0;
    148 #endif
    149 int	icmpreturndatabytes = 8;
    150 
    151 #if 0
    152 static int	ip_next_mtu __P((int, int));
    153 #else
    154 /*static*/ int	ip_next_mtu __P((int, int));
    155 #endif
    156 
    157 extern	struct timeval icmperrratelim;
    158 
    159 static void icmp_mtudisc __P((struct icmp *));
    160 static void icmp_mtudisc_timeout __P((struct rtentry *, struct rttimer *));
    161 
    162 static int icmp_ratelimit __P((const struct in_addr *, const int, const int));
    163 
    164 /*
    165  * Generate an error packet of type error
    166  * in response to bad packet ip.
    167  */
    168 void
    169 icmp_error(n, type, code, dest, destifp)
    170 	struct mbuf *n;
    171 	int type, code;
    172 	n_long dest;
    173 	struct ifnet *destifp;
    174 {
    175 	struct ip *oip = mtod(n, struct ip *), *nip;
    176 	unsigned oiplen = oip->ip_hl << 2;
    177 	struct icmp *icp;
    178 	struct mbuf *m;
    179 	unsigned icmplen;
    180 
    181 #ifdef ICMPPRINTFS
    182 	if (icmpprintfs)
    183 		printf("icmp_error(%x, %d, %d)\n", oip, type, code);
    184 #endif
    185 	if (type != ICMP_REDIRECT)
    186 		icmpstat.icps_error++;
    187 	/*
    188 	 * Don't send error if the original packet was encrypted.
    189 	 * Don't send error if not the first fragment of message.
    190 	 * Don't error if the old packet protocol was ICMP
    191 	 * error message, only known informational types.
    192 	 */
    193 	if (n->m_flags & M_DECRYPTED)
    194 		goto freeit;
    195 	if (oip->ip_off &~ (IP_MF|IP_DF))
    196 		goto freeit;
    197 	if (oip->ip_p == IPPROTO_ICMP && type != ICMP_REDIRECT &&
    198 	  n->m_len >= oiplen + ICMP_MINLEN &&
    199 	  !ICMP_INFOTYPE(((struct icmp *)((caddr_t)oip + oiplen))->icmp_type)) {
    200 		icmpstat.icps_oldicmp++;
    201 		goto freeit;
    202 	}
    203 	/* Don't send error in response to a multicast or broadcast packet */
    204 	if (n->m_flags & (M_BCAST|M_MCAST))
    205 		goto freeit;
    206 
    207 	/*
    208 	 * First, do a rate limitation check.
    209 	 */
    210 	if (icmp_ratelimit(&oip->ip_src, type, code)) {
    211 		/* XXX stat */
    212 		goto freeit;
    213 	}
    214 
    215 	/*
    216 	 * Now, formulate icmp message
    217 	 */
    218 	m = m_gethdr(M_DONTWAIT, MT_HEADER);
    219 	if (m == NULL)
    220 		goto freeit;
    221 	icmplen = oiplen + min(icmpreturndatabytes, oip->ip_len - oiplen);
    222 	m->m_len = icmplen + ICMP_MINLEN;
    223 	MH_ALIGN(m, m->m_len);
    224 	icp = mtod(m, struct icmp *);
    225 	if ((u_int)type > ICMP_MAXTYPE)
    226 		panic("icmp_error");
    227 	icmpstat.icps_outhist[type]++;
    228 	icp->icmp_type = type;
    229 	if (type == ICMP_REDIRECT)
    230 		icp->icmp_gwaddr.s_addr = dest;
    231 	else {
    232 		icp->icmp_void = 0;
    233 		/*
    234 		 * The following assignments assume an overlay with the
    235 		 * zeroed icmp_void field.
    236 		 */
    237 		if (type == ICMP_PARAMPROB) {
    238 			icp->icmp_pptr = code;
    239 			code = 0;
    240 		} else if (type == ICMP_UNREACH &&
    241 		    code == ICMP_UNREACH_NEEDFRAG && destifp)
    242 			icp->icmp_nextmtu = htons(destifp->if_mtu);
    243 	}
    244 
    245 	HTONS(oip->ip_off);
    246 	HTONS(oip->ip_len);
    247 	icp->icmp_code = code;
    248 	m_copydata(n, 0, icmplen, (caddr_t)&icp->icmp_ip);
    249 	nip = &icp->icmp_ip;
    250 
    251 	/*
    252 	 * Now, copy old ip header (without options)
    253 	 * in front of icmp message.
    254 	 */
    255 	if (m->m_data - sizeof(struct ip) < m->m_pktdat)
    256 		panic("icmp len");
    257 	m->m_data -= sizeof(struct ip);
    258 	m->m_len += sizeof(struct ip);
    259 	m->m_pkthdr.len = m->m_len;
    260 	m->m_pkthdr.rcvif = n->m_pkthdr.rcvif;
    261 	nip = mtod(m, struct ip *);
    262 	/* ip_v set in ip_output */
    263 	nip->ip_hl = sizeof(struct ip) >> 2;
    264 	nip->ip_tos = 0;
    265 	nip->ip_len = m->m_len;
    266 	/* ip_id set in ip_output */
    267 	nip->ip_off = 0;
    268 	/* ip_ttl set in icmp_reflect */
    269 	nip->ip_p = IPPROTO_ICMP;
    270 	nip->ip_src = oip->ip_src;
    271 	nip->ip_dst = oip->ip_dst;
    272 	icmp_reflect(m);
    273 
    274 freeit:
    275 	m_freem(n);
    276 }
    277 
    278 static struct sockaddr_in icmpsrc = { sizeof (struct sockaddr_in), AF_INET };
    279 static struct sockaddr_in icmpdst = { sizeof (struct sockaddr_in), AF_INET };
    280 static struct sockaddr_in icmpgw = { sizeof (struct sockaddr_in), AF_INET };
    281 struct sockaddr_in icmpmask = { 8, 0 };
    282 
    283 /*
    284  * Process a received ICMP message.
    285  */
    286 void
    287 #if __STDC__
    288 icmp_input(struct mbuf *m, ...)
    289 #else
    290 icmp_input(m, va_alist)
    291 	struct mbuf *m;
    292 	va_dcl
    293 #endif
    294 {
    295 	int proto;
    296 	struct icmp *icp;
    297 	struct ip *ip = mtod(m, struct ip *);
    298 	int icmplen;
    299 	int i;
    300 	struct in_ifaddr *ia;
    301 	void *(*ctlfunc) __P((int, struct sockaddr *, void *));
    302 	int code;
    303 	int hlen;
    304 	va_list ap;
    305 
    306 	va_start(ap, m);
    307 	hlen = va_arg(ap, int);
    308 	proto = va_arg(ap, int);
    309 	va_end(ap);
    310 
    311 	/*
    312 	 * Locate icmp structure in mbuf, and check
    313 	 * that not corrupted and of at least minimum length.
    314 	 */
    315 	icmplen = ip->ip_len - hlen;
    316 #ifdef ICMPPRINTFS
    317 	if (icmpprintfs)
    318 		printf("icmp_input from %x to %x, len %d\n",
    319 		    ntohl(ip->ip_src.s_addr), ntohl(ip->ip_dst.s_addr),
    320 		    icmplen);
    321 #endif
    322 	if (icmplen < ICMP_MINLEN) {
    323 		icmpstat.icps_tooshort++;
    324 		goto freeit;
    325 	}
    326 	i = hlen + min(icmplen, ICMP_ADVLENMIN);
    327 	if (m->m_len < i && (m = m_pullup(m, i)) == 0) {
    328 		icmpstat.icps_tooshort++;
    329 		return;
    330 	}
    331 	ip = mtod(m, struct ip *);
    332 	m->m_len -= hlen;
    333 	m->m_data += hlen;
    334 	icp = mtod(m, struct icmp *);
    335 	if (in_cksum(m, icmplen)) {
    336 		icmpstat.icps_checksum++;
    337 		goto freeit;
    338 	}
    339 	m->m_len += hlen;
    340 	m->m_data -= hlen;
    341 
    342 #ifdef ICMPPRINTFS
    343 	/*
    344 	 * Message type specific processing.
    345 	 */
    346 	if (icmpprintfs)
    347 		printf("icmp_input, type %d code %d\n", icp->icmp_type,
    348 		    icp->icmp_code);
    349 #endif
    350 #ifdef IPSEC
    351 	/* drop it if it does not match the policy */
    352 	if (ipsec4_in_reject(m, NULL)) {
    353 		ipsecstat.in_polvio++;
    354 		goto freeit;
    355 	}
    356 #endif
    357 	if (icp->icmp_type > ICMP_MAXTYPE)
    358 		goto raw;
    359 	icmpstat.icps_inhist[icp->icmp_type]++;
    360 	code = icp->icmp_code;
    361 	switch (icp->icmp_type) {
    362 
    363 	case ICMP_UNREACH:
    364 		switch (code) {
    365 			case ICMP_UNREACH_NET:
    366 			case ICMP_UNREACH_HOST:
    367 			case ICMP_UNREACH_PROTOCOL:
    368 			case ICMP_UNREACH_PORT:
    369 			case ICMP_UNREACH_SRCFAIL:
    370 				code += PRC_UNREACH_NET;
    371 				break;
    372 
    373 			case ICMP_UNREACH_NEEDFRAG:
    374 				code = PRC_MSGSIZE;
    375 				break;
    376 
    377 			case ICMP_UNREACH_NET_UNKNOWN:
    378 			case ICMP_UNREACH_NET_PROHIB:
    379 			case ICMP_UNREACH_TOSNET:
    380 				code = PRC_UNREACH_NET;
    381 				break;
    382 
    383 			case ICMP_UNREACH_HOST_UNKNOWN:
    384 			case ICMP_UNREACH_ISOLATED:
    385 			case ICMP_UNREACH_HOST_PROHIB:
    386 			case ICMP_UNREACH_TOSHOST:
    387 				code = PRC_UNREACH_HOST;
    388 				break;
    389 
    390 			default:
    391 				goto badcode;
    392 		}
    393 		goto deliver;
    394 
    395 	case ICMP_TIMXCEED:
    396 		if (code > 1)
    397 			goto badcode;
    398 		code += PRC_TIMXCEED_INTRANS;
    399 		goto deliver;
    400 
    401 	case ICMP_PARAMPROB:
    402 		if (code > 1)
    403 			goto badcode;
    404 		code = PRC_PARAMPROB;
    405 		goto deliver;
    406 
    407 	case ICMP_SOURCEQUENCH:
    408 		if (code)
    409 			goto badcode;
    410 		code = PRC_QUENCH;
    411 		goto deliver;
    412 
    413 	deliver:
    414 		/*
    415 		 * Problem with datagram; advise higher level routines.
    416 		 */
    417 		if (icmplen < ICMP_ADVLENMIN || icmplen < ICMP_ADVLEN(icp) ||
    418 		    icp->icmp_ip.ip_hl < (sizeof(struct ip) >> 2)) {
    419 			icmpstat.icps_badlen++;
    420 			goto freeit;
    421 		}
    422 		if (IN_MULTICAST(icp->icmp_ip.ip_dst.s_addr))
    423 			goto badcode;
    424 		NTOHS(icp->icmp_ip.ip_len);
    425 #ifdef ICMPPRINTFS
    426 		if (icmpprintfs)
    427 			printf("deliver to protocol %d\n", icp->icmp_ip.ip_p);
    428 #endif
    429 		icmpsrc.sin_addr = icp->icmp_ip.ip_dst;
    430 		if (code == PRC_MSGSIZE && ip_mtudisc)
    431 			icmp_mtudisc(icp);
    432 		/*
    433 		 * XXX if the packet contains [IPv4 AH TCP], we can't make a
    434 		 * notification to TCP layer.
    435 		 */
    436 		ctlfunc = inetsw[ip_protox[icp->icmp_ip.ip_p]].pr_ctlinput;
    437 		if (ctlfunc)
    438 			(*ctlfunc)(code, sintosa(&icmpsrc), &icp->icmp_ip);
    439 		break;
    440 
    441 	badcode:
    442 		icmpstat.icps_badcode++;
    443 		break;
    444 
    445 	case ICMP_ECHO:
    446 		icp->icmp_type = ICMP_ECHOREPLY;
    447 		goto reflect;
    448 
    449 	case ICMP_TSTAMP:
    450 		if (icmplen < ICMP_TSLEN) {
    451 			icmpstat.icps_badlen++;
    452 			break;
    453 		}
    454 		icp->icmp_type = ICMP_TSTAMPREPLY;
    455 		icp->icmp_rtime = iptime();
    456 		icp->icmp_ttime = icp->icmp_rtime;	/* bogus, do later! */
    457 		goto reflect;
    458 
    459 	case ICMP_MASKREQ:
    460 		if (icmpmaskrepl == 0)
    461 			break;
    462 		/*
    463 		 * We are not able to respond with all ones broadcast
    464 		 * unless we receive it over a point-to-point interface.
    465 		 */
    466 		if (icmplen < ICMP_MASKLEN) {
    467 			icmpstat.icps_badlen++;
    468 			break;
    469 		}
    470 		if (ip->ip_dst.s_addr == INADDR_BROADCAST ||
    471 		    in_nullhost(ip->ip_dst))
    472 			icmpdst.sin_addr = ip->ip_src;
    473 		else
    474 			icmpdst.sin_addr = ip->ip_dst;
    475 		ia = ifatoia(ifaof_ifpforaddr(sintosa(&icmpdst),
    476 		    m->m_pkthdr.rcvif));
    477 		if (ia == 0)
    478 			break;
    479 		icp->icmp_type = ICMP_MASKREPLY;
    480 		icp->icmp_mask = ia->ia_sockmask.sin_addr.s_addr;
    481 		if (in_nullhost(ip->ip_src)) {
    482 			if (ia->ia_ifp->if_flags & IFF_BROADCAST)
    483 				ip->ip_src = ia->ia_broadaddr.sin_addr;
    484 			else if (ia->ia_ifp->if_flags & IFF_POINTOPOINT)
    485 				ip->ip_src = ia->ia_dstaddr.sin_addr;
    486 		}
    487 reflect:
    488 		icmpstat.icps_reflect++;
    489 		icmpstat.icps_outhist[icp->icmp_type]++;
    490 		icmp_reflect(m);
    491 		return;
    492 
    493 	case ICMP_REDIRECT:
    494 		if (code > 3)
    495 			goto badcode;
    496 		if (icmplen < ICMP_ADVLENMIN || icmplen < ICMP_ADVLEN(icp) ||
    497 		    icp->icmp_ip.ip_hl < (sizeof(struct ip) >> 2)) {
    498 			icmpstat.icps_badlen++;
    499 			break;
    500 		}
    501 		/*
    502 		 * Short circuit routing redirects to force
    503 		 * immediate change in the kernel's routing
    504 		 * tables.  The message is also handed to anyone
    505 		 * listening on a raw socket (e.g. the routing
    506 		 * daemon for use in updating its tables).
    507 		 */
    508 		icmpgw.sin_addr = ip->ip_src;
    509 		icmpdst.sin_addr = icp->icmp_gwaddr;
    510 #ifdef	ICMPPRINTFS
    511 		if (icmpprintfs)
    512 			printf("redirect dst %x to %x\n", icp->icmp_ip.ip_dst,
    513 			    icp->icmp_gwaddr);
    514 #endif
    515 		icmpsrc.sin_addr = icp->icmp_ip.ip_dst;
    516 		rtredirect(sintosa(&icmpsrc), sintosa(&icmpdst),
    517 		    (struct sockaddr *)0, RTF_GATEWAY | RTF_HOST,
    518 		    sintosa(&icmpgw), (struct rtentry **)0);
    519 		pfctlinput(PRC_REDIRECT_HOST, sintosa(&icmpsrc));
    520 #ifdef IPSEC
    521 		key_sa_routechange((struct sockaddr *)&icmpsrc);
    522 #endif
    523 		break;
    524 
    525 	/*
    526 	 * No kernel processing for the following;
    527 	 * just fall through to send to raw listener.
    528 	 */
    529 	case ICMP_ECHOREPLY:
    530 	case ICMP_ROUTERADVERT:
    531 	case ICMP_ROUTERSOLICIT:
    532 	case ICMP_TSTAMPREPLY:
    533 	case ICMP_IREQREPLY:
    534 	case ICMP_MASKREPLY:
    535 	default:
    536 		break;
    537 	}
    538 
    539 raw:
    540 	rip_input(m, hlen, proto);
    541 	return;
    542 
    543 freeit:
    544 	m_freem(m);
    545 	return;
    546 }
    547 
    548 /*
    549  * Reflect the ip packet back to the source
    550  */
    551 void
    552 icmp_reflect(m)
    553 	struct mbuf *m;
    554 {
    555 	struct ip *ip = mtod(m, struct ip *);
    556 	struct in_ifaddr *ia;
    557 	struct ifaddr *ifa;
    558 	struct sockaddr_in *sin = 0;
    559 	struct in_addr t;
    560 	struct mbuf *opts = 0;
    561 	int optlen = (ip->ip_hl << 2) - sizeof(struct ip);
    562 
    563 	if (!in_canforward(ip->ip_src) &&
    564 	    ((ip->ip_src.s_addr & IN_CLASSA_NET) !=
    565 	     htonl(IN_LOOPBACKNET << IN_CLASSA_NSHIFT))) {
    566 		m_freem(m);	/* Bad return address */
    567 		goto done;	/* ip_output() will check for broadcast */
    568 	}
    569 	t = ip->ip_dst;
    570 	ip->ip_dst = ip->ip_src;
    571 	/*
    572 	 * If the incoming packet was addressed directly to us, use
    573 	 * dst as the src for the reply.  Otherwise (broadcast or
    574 	 * anonymous), use an address which corresponds to the
    575 	 * incoming interface, with a preference for the address which
    576 	 * corresponds to the route to the destination of the ICMP.
    577 	 */
    578 
    579 	/* Look for packet addressed to us */
    580 	INADDR_TO_IA(t, ia);
    581 
    582 	/* look for packet sent to broadcast address */
    583 	if (ia == NULL && (m->m_pkthdr.rcvif->if_flags & IFF_BROADCAST)) {
    584 		for (ifa = m->m_pkthdr.rcvif->if_addrlist.tqh_first;
    585 		    ifa != NULL; ifa = ifa->ifa_list.tqe_next) {
    586 			if (ifa->ifa_addr->sa_family != AF_INET)
    587 				continue;
    588 			if (in_hosteq(t,ifatoia(ifa)->ia_broadaddr.sin_addr)) {
    589 				ia = ifatoia(ifa);
    590 				break;
    591 			}
    592 		}
    593 	}
    594 
    595 	if (ia)
    596 		sin = &ia->ia_addr;
    597 
    598 	icmpdst.sin_addr = t;
    599 
    600 	/* if the packet is addressed somewhere else, compute the
    601 	   source address for packets routed back to the source, and
    602 	   use that, if it's an address on the interface which
    603 	   received the packet */
    604 	if (sin == (struct sockaddr_in *)0) {
    605 		struct sockaddr_in sin_dst;
    606 		struct route icmproute;
    607 		int errornum;
    608 
    609 		sin_dst.sin_family = AF_INET;
    610 		sin_dst.sin_len = sizeof(struct sockaddr_in);
    611 		sin_dst.sin_addr = ip->ip_dst;
    612 		bzero(&icmproute, sizeof(icmproute));
    613 		errornum = 0;
    614 		sin = in_selectsrc(&sin_dst, &icmproute, 0, NULL, &errornum);
    615 		/* errornum is never used */
    616 		if (icmproute.ro_rt)
    617 			RTFREE(icmproute.ro_rt);
    618 		/* check to make sure sin is a source address on rcvif */
    619 		if (sin) {
    620 			t = sin->sin_addr;
    621 			sin = (struct sockaddr_in *)0;
    622 			INADDR_TO_IA(t, ia);
    623 			while (ia) {
    624 				if (ia->ia_ifp == m->m_pkthdr.rcvif) {
    625 					sin = &ia->ia_addr;
    626 					break;
    627 				}
    628 				NEXT_IA_WITH_SAME_ADDR(ia);
    629 			}
    630 		}
    631 	}
    632 
    633 	/* if it was not addressed to us, but the route doesn't go out
    634 	   the source interface, pick an address on the source
    635 	   interface.  This can happen when routing is asymmetric, or
    636 	   when the incoming packet was encapsulated */
    637 	if (sin == (struct sockaddr_in *)0) {
    638 		for (ifa = m->m_pkthdr.rcvif->if_addrlist.tqh_first;
    639 		     ifa != NULL; ifa = ifa->ifa_list.tqe_next) {
    640 			if (ifa->ifa_addr->sa_family != AF_INET)
    641 				continue;
    642 			sin = &(ifatoia(ifa)->ia_addr);
    643 			break;
    644 		}
    645 	}
    646 
    647 	/*
    648 	 * The following happens if the packet was not addressed to us,
    649 	 * and was received on an interface with no IP address:
    650 	 * We find the first AF_INET address on the first non-loopback
    651 	 * interface.
    652 	 */
    653 	if (sin == (struct sockaddr_in *)0)
    654 		for (ia = in_ifaddr.tqh_first; ia != NULL;
    655 		    ia = ia->ia_list.tqe_next) {
    656 			if (ia->ia_ifp->if_flags & IFF_LOOPBACK)
    657 				continue;
    658 			sin = &ia->ia_addr;
    659 			break;
    660 		}
    661 
    662 	/*
    663 	 * If we still didn't find an address, punt.  We could have an
    664 	 * interface up (and receiving packets) with no address.
    665 	 */
    666 	if (sin == (struct sockaddr_in *)0) {
    667 		m_freem(m);
    668 		goto done;
    669 	}
    670 
    671 	ip->ip_src = sin->sin_addr;
    672 	ip->ip_ttl = MAXTTL;
    673 
    674 	if (optlen > 0) {
    675 		u_char *cp;
    676 		int opt, cnt;
    677 		u_int len;
    678 
    679 		/*
    680 		 * Retrieve any source routing from the incoming packet;
    681 		 * add on any record-route or timestamp options.
    682 		 */
    683 		cp = (u_char *) (ip + 1);
    684 		if ((opts = ip_srcroute()) == 0 &&
    685 		    (opts = m_gethdr(M_DONTWAIT, MT_HEADER))) {
    686 			opts->m_len = sizeof(struct in_addr);
    687 			*mtod(opts, struct in_addr *) = zeroin_addr;
    688 		}
    689 		if (opts) {
    690 #ifdef ICMPPRINTFS
    691 		    if (icmpprintfs)
    692 			    printf("icmp_reflect optlen %d rt %d => ",
    693 				optlen, opts->m_len);
    694 #endif
    695 		    for (cnt = optlen; cnt > 0; cnt -= len, cp += len) {
    696 			    opt = cp[IPOPT_OPTVAL];
    697 			    if (opt == IPOPT_EOL)
    698 				    break;
    699 			    if (opt == IPOPT_NOP)
    700 				    len = 1;
    701 			    else {
    702 				    if (cnt < IPOPT_OLEN + sizeof(*cp))
    703 					    break;
    704 				    len = cp[IPOPT_OLEN];
    705 				    if (len < IPOPT_OLEN + sizeof(*cp) ||
    706 				        len > cnt)
    707 					    break;
    708 			    }
    709 			    /*
    710 			     * Should check for overflow, but it "can't happen"
    711 			     */
    712 			    if (opt == IPOPT_RR || opt == IPOPT_TS ||
    713 				opt == IPOPT_SECURITY) {
    714 				    bcopy((caddr_t)cp,
    715 					mtod(opts, caddr_t) + opts->m_len, len);
    716 				    opts->m_len += len;
    717 			    }
    718 		    }
    719 		    /* Terminate & pad, if necessary */
    720 		    if ((cnt = opts->m_len % 4) != 0) {
    721 			    for (; cnt < 4; cnt++) {
    722 				    *(mtod(opts, caddr_t) + opts->m_len) =
    723 					IPOPT_EOL;
    724 				    opts->m_len++;
    725 			    }
    726 		    }
    727 #ifdef ICMPPRINTFS
    728 		    if (icmpprintfs)
    729 			    printf("%d\n", opts->m_len);
    730 #endif
    731 		}
    732 		/*
    733 		 * Now strip out original options by copying rest of first
    734 		 * mbuf's data back, and adjust the IP length.
    735 		 */
    736 		ip->ip_len -= optlen;
    737 		ip->ip_hl = sizeof(struct ip) >> 2;
    738 		m->m_len -= optlen;
    739 		if (m->m_flags & M_PKTHDR)
    740 			m->m_pkthdr.len -= optlen;
    741 		optlen += sizeof(struct ip);
    742 		bcopy((caddr_t)ip + optlen, (caddr_t)(ip + 1),
    743 			 (unsigned)(m->m_len - sizeof(struct ip)));
    744 	}
    745 	m->m_flags &= ~(M_BCAST|M_MCAST);
    746 	icmp_send(m, opts);
    747 done:
    748 	if (opts)
    749 		(void)m_free(opts);
    750 }
    751 
    752 /*
    753  * Send an icmp packet back to the ip level,
    754  * after supplying a checksum.
    755  */
    756 void
    757 icmp_send(m, opts)
    758 	struct mbuf *m;
    759 	struct mbuf *opts;
    760 {
    761 	struct ip *ip = mtod(m, struct ip *);
    762 	int hlen;
    763 	struct icmp *icp;
    764 
    765 	hlen = ip->ip_hl << 2;
    766 	m->m_data += hlen;
    767 	m->m_len -= hlen;
    768 	icp = mtod(m, struct icmp *);
    769 	icp->icmp_cksum = 0;
    770 	icp->icmp_cksum = in_cksum(m, ip->ip_len - hlen);
    771 	m->m_data -= hlen;
    772 	m->m_len += hlen;
    773 #ifdef ICMPPRINTFS
    774 	if (icmpprintfs)
    775 		printf("icmp_send dst %x src %x\n", ip->ip_dst, ip->ip_src);
    776 #endif
    777 #ifdef IPSEC
    778 	/* Don't lookup socket */
    779 	ipsec_setsocket(m, NULL);
    780 #endif
    781 	(void) ip_output(m, opts, NULL, 0, NULL);
    782 }
    783 
    784 n_time
    785 iptime()
    786 {
    787 	struct timeval atv;
    788 	u_long t;
    789 
    790 	microtime(&atv);
    791 	t = (atv.tv_sec % (24*60*60)) * 1000 + atv.tv_usec / 1000;
    792 	return (htonl(t));
    793 }
    794 
    795 int
    796 icmp_sysctl(name, namelen, oldp, oldlenp, newp, newlen)
    797 	int *name;
    798 	u_int namelen;
    799 	void *oldp;
    800 	size_t *oldlenp;
    801 	void *newp;
    802 	size_t newlen;
    803 {
    804 	int arg, error, s;
    805 
    806 	/* All sysctl names at this level are terminal. */
    807 	if (namelen != 1)
    808 		return (ENOTDIR);
    809 
    810 	switch (name[0])
    811 	{
    812 	case ICMPCTL_MASKREPL:
    813 		error = sysctl_int(oldp, oldlenp, newp, newlen, &icmpmaskrepl);
    814 		break;
    815 	case ICMPCTL_ERRRATELIMIT:
    816 		/*
    817 		 * The sysctl specifies the rate in usec-between-icmp,
    818 		 * so we must convert from/to a timeval.
    819 		 */
    820 		arg = (icmperrratelim.tv_sec * 1000000) +
    821 		    icmperrratelim.tv_usec;
    822 		error = sysctl_int(oldp, oldlenp, newp, newlen, &arg);
    823 		if (error)
    824 			break;
    825 		if (arg >= 0) {
    826 			s = splsoftnet();
    827 			icmperrratelim.tv_sec = arg / 1000000;
    828 			icmperrratelim.tv_usec = arg % 1000000;
    829 			splx(s);
    830 		} else
    831 			error = EINVAL;
    832 		break;
    833 	case ICMPCTL_RETURNDATABYTES:
    834 		arg = icmpreturndatabytes;
    835 		error = sysctl_int(oldp, oldlenp, newp, newlen, &arg);
    836 		if (error)
    837 			break;
    838 		if ((arg >= 8) || (arg <= 512))
    839 			icmpreturndatabytes = arg;
    840 		else
    841 			error = EINVAL;
    842 		break;
    843 	default:
    844 		error = ENOPROTOOPT;
    845 		break;
    846 	}
    847 	return error;
    848 }
    849 
    850 static void
    851 icmp_mtudisc(icp)
    852 	struct icmp *icp;
    853 {
    854 	struct rtentry *rt;
    855 	struct sockaddr *dst = sintosa(&icmpsrc);
    856 	u_long mtu = ntohs(icp->icmp_nextmtu);  /* Why a long?  IPv6 */
    857 	int    error;
    858 
    859 	/* Table of common MTUs: */
    860 
    861 	static u_long mtu_table[] = {65535, 65280, 32000, 17914, 9180, 8166,
    862 				     4352, 2002, 1492, 1006, 508, 296, 68, 0};
    863 
    864 	rt = rtalloc1(dst, 1);
    865 	if (rt == 0)
    866 		return;
    867 
    868 	/* If we didn't get a host route, allocate one */
    869 
    870 	if ((rt->rt_flags & RTF_HOST) == 0) {
    871 		struct rtentry *nrt;
    872 
    873 		error = rtrequest((int) RTM_ADD, dst,
    874 		    (struct sockaddr *) rt->rt_gateway,
    875 		    (struct sockaddr *) 0,
    876 		    RTF_GATEWAY | RTF_HOST | RTF_DYNAMIC, &nrt);
    877 		if (error) {
    878 			rtfree(rt);
    879 			rtfree(nrt);
    880 			return;
    881 		}
    882 		nrt->rt_rmx = rt->rt_rmx;
    883 		rtfree(rt);
    884 		rt = nrt;
    885 	}
    886 	error = rt_timer_add(rt, icmp_mtudisc_timeout, ip_mtudisc_timeout_q);
    887 	if (error) {
    888 		rtfree(rt);
    889 		return;
    890 	}
    891 
    892 	if (mtu == 0) {
    893 		int i = 0;
    894 
    895 		mtu = icp->icmp_ip.ip_len; /* NTOHS happened in deliver: */
    896 		/* Some 4.2BSD-based routers incorrectly adjust the ip_len */
    897 		if (mtu > rt->rt_rmx.rmx_mtu && rt->rt_rmx.rmx_mtu != 0)
    898 			mtu -= (icp->icmp_ip.ip_hl << 2);
    899 
    900 		/* If we still can't guess a value, try the route */
    901 
    902 		if (mtu == 0) {
    903 			mtu = rt->rt_rmx.rmx_mtu;
    904 
    905 			/* If no route mtu, default to the interface mtu */
    906 
    907 			if (mtu == 0)
    908 				mtu = rt->rt_ifp->if_mtu;
    909 		}
    910 
    911 		for (i = 0; i < sizeof(mtu_table) / sizeof(mtu_table[0]); i++)
    912 			if (mtu > mtu_table[i]) {
    913 				mtu = mtu_table[i];
    914 				break;
    915 			}
    916 	}
    917 
    918 	/*
    919 	 * XXX:   RTV_MTU is overloaded, since the admin can set it
    920 	 *	  to turn off PMTU for a route, and the kernel can
    921 	 *	  set it to indicate a serious problem with PMTU
    922 	 *	  on a route.  We should be using a separate flag
    923 	 *	  for the kernel to indicate this.
    924 	 */
    925 
    926 	if ((rt->rt_rmx.rmx_locks & RTV_MTU) == 0) {
    927 		if (mtu < 296 || mtu > rt->rt_ifp->if_mtu)
    928 			rt->rt_rmx.rmx_locks |= RTV_MTU;
    929 		else if (rt->rt_rmx.rmx_mtu > mtu ||
    930 			 rt->rt_rmx.rmx_mtu == 0)
    931 			rt->rt_rmx.rmx_mtu = mtu;
    932 	}
    933 
    934 	if (rt)
    935 		rtfree(rt);
    936 }
    937 
    938 /*
    939  * Return the next larger or smaller MTU plateau (table from RFC 1191)
    940  * given current value MTU.  If DIR is less than zero, a larger plateau
    941  * is returned; otherwise, a smaller value is returned.
    942  */
    943 int
    944 ip_next_mtu(mtu, dir)	/* XXX */
    945 	int mtu;
    946 	int dir;
    947 {
    948 	static int mtutab[] = {
    949 		65535, 32000, 17914, 8166, 4352, 2002, 1492, 1006, 508, 296,
    950 		68, 0
    951 	};
    952 	int i;
    953 
    954 	for (i = 0; i < (sizeof mtutab) / (sizeof mtutab[0]); i++) {
    955 		if (mtu >= mtutab[i])
    956 			break;
    957 	}
    958 
    959 	if (dir < 0) {
    960 		if (i == 0) {
    961 			return 0;
    962 		} else {
    963 			return mtutab[i - 1];
    964 		}
    965 	} else {
    966 		if (mtutab[i] == 0) {
    967 			return 0;
    968 		} else if(mtu > mtutab[i]) {
    969 			return mtutab[i];
    970 		} else {
    971 			return mtutab[i + 1];
    972 		}
    973 	}
    974 }
    975 
    976 static void
    977 icmp_mtudisc_timeout(rt, r)
    978 	struct rtentry *rt;
    979 	struct rttimer *r;
    980 {
    981 	if (rt == NULL)
    982 		panic("icmp_mtudisc_timeout:  bad route to timeout");
    983 	if ((rt->rt_flags & (RTF_DYNAMIC | RTF_HOST)) ==
    984 	    (RTF_DYNAMIC | RTF_HOST)) {
    985 		rtrequest((int) RTM_DELETE, (struct sockaddr *)rt_key(rt),
    986 		    rt->rt_gateway, rt_mask(rt), rt->rt_flags, 0);
    987 	} else {
    988 		if ((rt->rt_rmx.rmx_locks & RTV_MTU) == 0) {
    989 			rt->rt_rmx.rmx_mtu = 0;
    990 		}
    991 	}
    992 }
    993 
    994 /*
    995  * Perform rate limit check.
    996  * Returns 0 if it is okay to send the icmp packet.
    997  * Returns 1 if the router SHOULD NOT send this icmp packet due to rate
    998  * limitation.
    999  *
   1000  * XXX per-destination/type check necessary?
   1001  */
   1002 static int
   1003 icmp_ratelimit(dst, type, code)
   1004 	const struct in_addr *dst;	/* not used at this moment */
   1005 	const int type;			/* not used at this moment */
   1006 	const int code;			/* not used at this moment */
   1007 {
   1008 	static struct timeval icmperrratelim_last;
   1009 
   1010 	/*
   1011 	 * ratecheck() returns true if it is okay to send.  We return
   1012 	 * true if it is not okay to send.
   1013 	 */
   1014 	return (ratecheck(&icmperrratelim_last, &icmperrratelim) == 0);
   1015 }
   1016