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