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