ip_icmp.c revision 105194
1/*
2 * Copyright (c) 1982, 1986, 1988, 1993
3 *	The Regents of the University of California.  All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright
9 *    notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 *    notice, this list of conditions and the following disclaimer in the
12 *    documentation and/or other materials provided with the distribution.
13 * 3. All advertising materials mentioning features or use of this software
14 *    must display the following acknowledgement:
15 *	This product includes software developed by the University of
16 *	California, Berkeley and its contributors.
17 * 4. Neither the name of the University nor the names of its contributors
18 *    may be used to endorse or promote products derived from this software
19 *    without specific prior written permission.
20 *
21 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
22 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24 * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
25 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
27 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
30 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
31 * SUCH DAMAGE.
32 *
33 *	@(#)ip_icmp.c	8.2 (Berkeley) 1/4/94
34 * $FreeBSD: head/sys/netinet/ip_icmp.c 105194 2002-10-16 01:54:46Z sam $
35 */
36
37#include "opt_ipsec.h"
38#include "opt_mac.h"
39
40#include <sys/param.h>
41#include <sys/systm.h>
42#include <sys/mac.h>
43#include <sys/mbuf.h>
44#include <sys/protosw.h>
45#include <sys/socket.h>
46#include <sys/time.h>
47#include <sys/kernel.h>
48#include <sys/sysctl.h>
49
50#include <net/if.h>
51#include <net/if_types.h>
52#include <net/route.h>
53
54#define _IP_VHL
55#include <netinet/in.h>
56#include <netinet/in_systm.h>
57#include <netinet/in_var.h>
58#include <netinet/ip.h>
59#include <netinet/ip_icmp.h>
60#include <netinet/ip_var.h>
61#include <netinet/icmp_var.h>
62
63#ifdef IPSEC
64#include <netinet6/ipsec.h>
65#include <netkey/key.h>
66#endif
67
68#include <machine/in_cksum.h>
69
70/*
71 * ICMP routines: error generation, receive packet processing, and
72 * routines to turnaround packets back to the originator, and
73 * host table maintenance routines.
74 */
75
76static struct	icmpstat icmpstat;
77SYSCTL_STRUCT(_net_inet_icmp, ICMPCTL_STATS, stats, CTLFLAG_RW,
78	&icmpstat, icmpstat, "");
79
80static int	icmpmaskrepl = 0;
81SYSCTL_INT(_net_inet_icmp, ICMPCTL_MASKREPL, maskrepl, CTLFLAG_RW,
82	&icmpmaskrepl, 0, "");
83
84static int	drop_redirect = 0;
85SYSCTL_INT(_net_inet_icmp, OID_AUTO, drop_redirect, CTLFLAG_RW,
86	&drop_redirect, 0, "");
87
88static int	log_redirect = 0;
89SYSCTL_INT(_net_inet_icmp, OID_AUTO, log_redirect, CTLFLAG_RW,
90	&log_redirect, 0, "");
91
92static int      icmplim = 200;
93SYSCTL_INT(_net_inet_icmp, ICMPCTL_ICMPLIM, icmplim, CTLFLAG_RW,
94	&icmplim, 0, "");
95
96static int	icmplim_output = 1;
97SYSCTL_INT(_net_inet_icmp, OID_AUTO, icmplim_output, CTLFLAG_RW,
98	&icmplim_output, 0, "");
99
100/*
101 * ICMP broadcast echo sysctl
102 */
103
104static int	icmpbmcastecho = 0;
105SYSCTL_INT(_net_inet_icmp, OID_AUTO, bmcastecho, CTLFLAG_RW,
106	&icmpbmcastecho, 0, "");
107
108
109#ifdef ICMPPRINTFS
110int	icmpprintfs = 0;
111#endif
112
113static void	icmp_reflect(struct mbuf *);
114static void	icmp_send(struct mbuf *, struct mbuf *, struct route *);
115static int	ip_next_mtu(int, int);
116
117extern	struct protosw inetsw[];
118
119/*
120 * Generate an error packet of type error
121 * in response to bad packet ip.
122 */
123void
124icmp_error(n, type, code, dest, destifp)
125	struct mbuf *n;
126	int type, code;
127	n_long dest;
128	struct ifnet *destifp;
129{
130	register struct ip *oip = mtod(n, struct ip *), *nip;
131	register unsigned oiplen = IP_VHL_HL(oip->ip_vhl) << 2;
132	register struct icmp *icp;
133	register struct mbuf *m;
134	unsigned icmplen;
135
136#ifdef ICMPPRINTFS
137	if (icmpprintfs)
138		printf("icmp_error(%p, %x, %d)\n", oip, type, code);
139#endif
140	if (type != ICMP_REDIRECT)
141		icmpstat.icps_error++;
142	/*
143	 * Don't send error if not the first fragment of message.
144	 * Don't error if the old packet protocol was ICMP
145	 * error message, only known informational types.
146	 */
147	if (oip->ip_off &~ (IP_MF|IP_DF))
148		goto freeit;
149	if (oip->ip_p == IPPROTO_ICMP && type != ICMP_REDIRECT &&
150	  n->m_len >= oiplen + ICMP_MINLEN &&
151	  !ICMP_INFOTYPE(((struct icmp *)((caddr_t)oip + oiplen))->icmp_type)) {
152		icmpstat.icps_oldicmp++;
153		goto freeit;
154	}
155	/* Don't send error in response to a multicast or broadcast packet */
156	if (n->m_flags & (M_BCAST|M_MCAST))
157		goto freeit;
158	/*
159	 * First, formulate icmp message
160	 */
161	m = m_gethdr(M_DONTWAIT, MT_HEADER);
162	if (m == NULL)
163		goto freeit;
164#ifdef MAC
165	mac_create_mbuf_netlayer(n, m);
166#endif
167	icmplen = min(oiplen + 8, oip->ip_len);
168	if (icmplen < sizeof(struct ip))
169		panic("icmp_error: bad length");
170	m->m_len = icmplen + ICMP_MINLEN;
171	MH_ALIGN(m, m->m_len);
172	icp = mtod(m, struct icmp *);
173	if ((u_int)type > ICMP_MAXTYPE)
174		panic("icmp_error");
175	icmpstat.icps_outhist[type]++;
176	icp->icmp_type = type;
177	if (type == ICMP_REDIRECT)
178		icp->icmp_gwaddr.s_addr = dest;
179	else {
180		icp->icmp_void = 0;
181		/*
182		 * The following assignments assume an overlay with the
183		 * zeroed icmp_void field.
184		 */
185		if (type == ICMP_PARAMPROB) {
186			icp->icmp_pptr = code;
187			code = 0;
188		} else if (type == ICMP_UNREACH &&
189			code == ICMP_UNREACH_NEEDFRAG && destifp) {
190			icp->icmp_nextmtu = htons(destifp->if_mtu);
191		}
192	}
193
194	icp->icmp_code = code;
195	m_copydata(n, 0, icmplen, (caddr_t)&icp->icmp_ip);
196	nip = &icp->icmp_ip;
197
198	/*
199	 * Convert fields to network representation.
200	 */
201	nip->ip_len = htons(nip->ip_len);
202	nip->ip_off = htons(nip->ip_off);
203
204	/*
205	 * Now, copy old ip header (without options)
206	 * in front of icmp message.
207	 */
208	if (m->m_data - sizeof(struct ip) < m->m_pktdat)
209		panic("icmp len");
210	m->m_data -= sizeof(struct ip);
211	m->m_len += sizeof(struct ip);
212	m->m_pkthdr.len = m->m_len;
213	m->m_pkthdr.rcvif = n->m_pkthdr.rcvif;
214	nip = mtod(m, struct ip *);
215	bcopy((caddr_t)oip, (caddr_t)nip, sizeof(struct ip));
216	nip->ip_len = m->m_len;
217	nip->ip_vhl = IP_VHL_BORING;
218	nip->ip_p = IPPROTO_ICMP;
219	nip->ip_tos = 0;
220	icmp_reflect(m);
221
222freeit:
223	m_freem(n);
224}
225
226static struct sockaddr_in icmpsrc = { sizeof (struct sockaddr_in), AF_INET };
227static struct sockaddr_in icmpdst = { sizeof (struct sockaddr_in), AF_INET };
228static struct sockaddr_in icmpgw = { sizeof (struct sockaddr_in), AF_INET };
229
230/*
231 * Process a received ICMP message.
232 */
233void
234icmp_input(m, off)
235	register struct mbuf *m;
236	int off;
237{
238	int hlen = off;
239	register struct icmp *icp;
240	register struct ip *ip = mtod(m, struct ip *);
241	int icmplen = ip->ip_len;
242	register int i;
243	struct in_ifaddr *ia;
244	void (*ctlfunc)(int, struct sockaddr *, void *);
245	int code;
246
247	/*
248	 * Locate icmp structure in mbuf, and check
249	 * that not corrupted and of at least minimum length.
250	 */
251#ifdef ICMPPRINTFS
252	if (icmpprintfs) {
253		char buf[4 * sizeof "123"];
254		strcpy(buf, inet_ntoa(ip->ip_src));
255		printf("icmp_input from %s to %s, len %d\n",
256		       buf, inet_ntoa(ip->ip_dst), icmplen);
257	}
258#endif
259	if (icmplen < ICMP_MINLEN) {
260		icmpstat.icps_tooshort++;
261		goto freeit;
262	}
263	i = hlen + min(icmplen, ICMP_ADVLENMIN);
264	if (m->m_len < i && (m = m_pullup(m, i)) == 0)  {
265		icmpstat.icps_tooshort++;
266		return;
267	}
268	ip = mtod(m, struct ip *);
269	m->m_len -= hlen;
270	m->m_data += hlen;
271	icp = mtod(m, struct icmp *);
272	if (in_cksum(m, icmplen)) {
273		icmpstat.icps_checksum++;
274		goto freeit;
275	}
276	m->m_len += hlen;
277	m->m_data -= hlen;
278
279	if (m->m_pkthdr.rcvif && m->m_pkthdr.rcvif->if_type == IFT_FAITH) {
280		/*
281		 * Deliver very specific ICMP type only.
282		 */
283		switch (icp->icmp_type) {
284		case ICMP_UNREACH:
285		case ICMP_TIMXCEED:
286			break;
287		default:
288			goto freeit;
289		}
290	}
291
292#ifdef ICMPPRINTFS
293	if (icmpprintfs)
294		printf("icmp_input, type %d code %d\n", icp->icmp_type,
295		    icp->icmp_code);
296#endif
297
298	/*
299	 * Message type specific processing.
300	 */
301	if (icp->icmp_type > ICMP_MAXTYPE)
302		goto raw;
303	icmpstat.icps_inhist[icp->icmp_type]++;
304	code = icp->icmp_code;
305	switch (icp->icmp_type) {
306
307	case ICMP_UNREACH:
308		switch (code) {
309			case ICMP_UNREACH_NET:
310			case ICMP_UNREACH_HOST:
311			case ICMP_UNREACH_SRCFAIL:
312			case ICMP_UNREACH_NET_UNKNOWN:
313			case ICMP_UNREACH_HOST_UNKNOWN:
314			case ICMP_UNREACH_ISOLATED:
315			case ICMP_UNREACH_TOSNET:
316			case ICMP_UNREACH_TOSHOST:
317			case ICMP_UNREACH_HOST_PRECEDENCE:
318			case ICMP_UNREACH_PRECEDENCE_CUTOFF:
319				code = PRC_UNREACH_NET;
320				break;
321
322			case ICMP_UNREACH_NEEDFRAG:
323				code = PRC_MSGSIZE;
324				break;
325
326			/*
327			 * RFC 1122, Sections 3.2.2.1 and 4.2.3.9.
328			 * Treat subcodes 2,3 as immediate RST
329			 */
330			case ICMP_UNREACH_PROTOCOL:
331			case ICMP_UNREACH_PORT:
332				code = PRC_UNREACH_PORT;
333				break;
334
335			case ICMP_UNREACH_NET_PROHIB:
336			case ICMP_UNREACH_HOST_PROHIB:
337			case ICMP_UNREACH_FILTER_PROHIB:
338				code = PRC_UNREACH_ADMIN_PROHIB;
339				break;
340
341			default:
342				goto badcode;
343		}
344		goto deliver;
345
346	case ICMP_TIMXCEED:
347		if (code > 1)
348			goto badcode;
349		code += PRC_TIMXCEED_INTRANS;
350		goto deliver;
351
352	case ICMP_PARAMPROB:
353		if (code > 1)
354			goto badcode;
355		code = PRC_PARAMPROB;
356		goto deliver;
357
358	case ICMP_SOURCEQUENCH:
359		if (code)
360			goto badcode;
361		code = PRC_QUENCH;
362	deliver:
363		/*
364		 * Problem with datagram; advise higher level routines.
365		 */
366		if (icmplen < ICMP_ADVLENMIN || icmplen < ICMP_ADVLEN(icp) ||
367		    IP_VHL_HL(icp->icmp_ip.ip_vhl) < (sizeof(struct ip) >> 2)) {
368			icmpstat.icps_badlen++;
369			goto freeit;
370		}
371		icp->icmp_ip.ip_len = ntohs(icp->icmp_ip.ip_len);
372		/* Discard ICMP's in response to multicast packets */
373		if (IN_MULTICAST(ntohl(icp->icmp_ip.ip_dst.s_addr)))
374			goto badcode;
375#ifdef ICMPPRINTFS
376		if (icmpprintfs)
377			printf("deliver to protocol %d\n", icp->icmp_ip.ip_p);
378#endif
379		icmpsrc.sin_addr = icp->icmp_ip.ip_dst;
380#if 1
381		/*
382		 * MTU discovery:
383		 * If we got a needfrag and there is a host route to the
384		 * original destination, and the MTU is not locked, then
385		 * set the MTU in the route to the suggested new value
386		 * (if given) and then notify as usual.  The ULPs will
387		 * notice that the MTU has changed and adapt accordingly.
388		 * If no new MTU was suggested, then we guess a new one
389		 * less than the current value.  If the new MTU is
390		 * unreasonably small (arbitrarily set at 296), then
391		 * we reset the MTU to the interface value and enable the
392		 * lock bit, indicating that we are no longer doing MTU
393		 * discovery.
394		 */
395		if (code == PRC_MSGSIZE) {
396			struct rtentry *rt;
397			int mtu;
398
399			rt = rtalloc1((struct sockaddr *)&icmpsrc, 0,
400				      RTF_CLONING | RTF_PRCLONING);
401			if (rt && (rt->rt_flags & RTF_HOST)
402			    && !(rt->rt_rmx.rmx_locks & RTV_MTU)) {
403				mtu = ntohs(icp->icmp_nextmtu);
404				if (!mtu)
405					mtu = ip_next_mtu(rt->rt_rmx.rmx_mtu,
406							  1);
407#ifdef DEBUG_MTUDISC
408				printf("MTU for %s reduced to %d\n",
409					inet_ntoa(icmpsrc.sin_addr), mtu);
410#endif
411				if (mtu < 296) {
412					/* rt->rt_rmx.rmx_mtu =
413						rt->rt_ifp->if_mtu; */
414					rt->rt_rmx.rmx_locks |= RTV_MTU;
415				} else if (rt->rt_rmx.rmx_mtu > mtu) {
416					rt->rt_rmx.rmx_mtu = mtu;
417				}
418			}
419			if (rt)
420				RTFREE(rt);
421		}
422
423#endif
424		/*
425		 * XXX if the packet contains [IPv4 AH TCP], we can't make a
426		 * notification to TCP layer.
427		 */
428		ctlfunc = inetsw[ip_protox[icp->icmp_ip.ip_p]].pr_ctlinput;
429		if (ctlfunc)
430			(*ctlfunc)(code, (struct sockaddr *)&icmpsrc,
431				   (void *)&icp->icmp_ip);
432		break;
433
434	badcode:
435		icmpstat.icps_badcode++;
436		break;
437
438	case ICMP_ECHO:
439		if (!icmpbmcastecho
440		    && (m->m_flags & (M_MCAST | M_BCAST)) != 0) {
441			icmpstat.icps_bmcastecho++;
442			break;
443		}
444		icp->icmp_type = ICMP_ECHOREPLY;
445		if (badport_bandlim(BANDLIM_ICMP_ECHO) < 0)
446			goto freeit;
447		else
448			goto reflect;
449
450	case ICMP_TSTAMP:
451		if (!icmpbmcastecho
452		    && (m->m_flags & (M_MCAST | M_BCAST)) != 0) {
453			icmpstat.icps_bmcasttstamp++;
454			break;
455		}
456		if (icmplen < ICMP_TSLEN) {
457			icmpstat.icps_badlen++;
458			break;
459		}
460		icp->icmp_type = ICMP_TSTAMPREPLY;
461		icp->icmp_rtime = iptime();
462		icp->icmp_ttime = icp->icmp_rtime;	/* bogus, do later! */
463		if (badport_bandlim(BANDLIM_ICMP_TSTAMP) < 0)
464			goto freeit;
465		else
466			goto reflect;
467
468	case ICMP_MASKREQ:
469		if (icmpmaskrepl == 0)
470			break;
471		/*
472		 * We are not able to respond with all ones broadcast
473		 * unless we receive it over a point-to-point interface.
474		 */
475		if (icmplen < ICMP_MASKLEN)
476			break;
477		switch (ip->ip_dst.s_addr) {
478
479		case INADDR_BROADCAST:
480		case INADDR_ANY:
481			icmpdst.sin_addr = ip->ip_src;
482			break;
483
484		default:
485			icmpdst.sin_addr = ip->ip_dst;
486		}
487		ia = (struct in_ifaddr *)ifaof_ifpforaddr(
488			    (struct sockaddr *)&icmpdst, m->m_pkthdr.rcvif);
489		if (ia == 0)
490			break;
491		if (ia->ia_ifp == 0)
492			break;
493		icp->icmp_type = ICMP_MASKREPLY;
494		icp->icmp_mask = ia->ia_sockmask.sin_addr.s_addr;
495		if (ip->ip_src.s_addr == 0) {
496			if (ia->ia_ifp->if_flags & IFF_BROADCAST)
497			    ip->ip_src = satosin(&ia->ia_broadaddr)->sin_addr;
498			else if (ia->ia_ifp->if_flags & IFF_POINTOPOINT)
499			    ip->ip_src = satosin(&ia->ia_dstaddr)->sin_addr;
500		}
501reflect:
502		ip->ip_len += hlen;	/* since ip_input deducts this */
503		icmpstat.icps_reflect++;
504		icmpstat.icps_outhist[icp->icmp_type]++;
505		icmp_reflect(m);
506		return;
507
508	case ICMP_REDIRECT:
509		if (log_redirect) {
510			u_long src, dst, gw;
511
512			src = ntohl(ip->ip_src.s_addr);
513			dst = ntohl(icp->icmp_ip.ip_dst.s_addr);
514			gw = ntohl(icp->icmp_gwaddr.s_addr);
515			printf("icmp redirect from %d.%d.%d.%d: "
516			       "%d.%d.%d.%d => %d.%d.%d.%d\n",
517			       (int)(src >> 24), (int)((src >> 16) & 0xff),
518			       (int)((src >> 8) & 0xff), (int)(src & 0xff),
519			       (int)(dst >> 24), (int)((dst >> 16) & 0xff),
520			       (int)((dst >> 8) & 0xff), (int)(dst & 0xff),
521			       (int)(gw >> 24), (int)((gw >> 16) & 0xff),
522			       (int)((gw >> 8) & 0xff), (int)(gw & 0xff));
523		}
524		if (drop_redirect)
525			break;
526		if (code > 3)
527			goto badcode;
528		if (icmplen < ICMP_ADVLENMIN || icmplen < ICMP_ADVLEN(icp) ||
529		    IP_VHL_HL(icp->icmp_ip.ip_vhl) < (sizeof(struct ip) >> 2)) {
530			icmpstat.icps_badlen++;
531			break;
532		}
533		/*
534		 * Short circuit routing redirects to force
535		 * immediate change in the kernel's routing
536		 * tables.  The message is also handed to anyone
537		 * listening on a raw socket (e.g. the routing
538		 * daemon for use in updating its tables).
539		 */
540		icmpgw.sin_addr = ip->ip_src;
541		icmpdst.sin_addr = icp->icmp_gwaddr;
542#ifdef	ICMPPRINTFS
543		if (icmpprintfs) {
544			char buf[4 * sizeof "123"];
545			strcpy(buf, inet_ntoa(icp->icmp_ip.ip_dst));
546
547			printf("redirect dst %s to %s\n",
548			       buf, inet_ntoa(icp->icmp_gwaddr));
549		}
550#endif
551		icmpsrc.sin_addr = icp->icmp_ip.ip_dst;
552		rtredirect((struct sockaddr *)&icmpsrc,
553		  (struct sockaddr *)&icmpdst,
554		  (struct sockaddr *)0, RTF_GATEWAY | RTF_HOST,
555		  (struct sockaddr *)&icmpgw, (struct rtentry **)0);
556		pfctlinput(PRC_REDIRECT_HOST, (struct sockaddr *)&icmpsrc);
557#ifdef IPSEC
558		key_sa_routechange((struct sockaddr *)&icmpsrc);
559#endif
560		break;
561
562	/*
563	 * No kernel processing for the following;
564	 * just fall through to send to raw listener.
565	 */
566	case ICMP_ECHOREPLY:
567	case ICMP_ROUTERADVERT:
568	case ICMP_ROUTERSOLICIT:
569	case ICMP_TSTAMPREPLY:
570	case ICMP_IREQREPLY:
571	case ICMP_MASKREPLY:
572	default:
573		break;
574	}
575
576raw:
577	rip_input(m, off);
578	return;
579
580freeit:
581	m_freem(m);
582}
583
584/*
585 * Reflect the ip packet back to the source
586 */
587static void
588icmp_reflect(m)
589	struct mbuf *m;
590{
591	struct ip *ip = mtod(m, struct ip *);
592	struct ifaddr *ifa;
593	struct in_ifaddr *ia;
594	struct in_addr t;
595	struct mbuf *opts = 0;
596	int optlen = (IP_VHL_HL(ip->ip_vhl) << 2) - sizeof(struct ip);
597	struct route *ro = NULL, rt;
598
599	if (!in_canforward(ip->ip_src) &&
600	    ((ntohl(ip->ip_src.s_addr) & IN_CLASSA_NET) !=
601	     (IN_LOOPBACKNET << IN_CLASSA_NSHIFT))) {
602		m_freem(m);	/* Bad return address */
603		icmpstat.icps_badaddr++;
604		goto done;	/* Ip_output() will check for broadcast */
605	}
606	t = ip->ip_dst;
607	ip->ip_dst = ip->ip_src;
608	ro = &rt;
609	bzero(ro, sizeof(*ro));
610	/*
611	 * If the incoming packet was addressed directly to us,
612	 * use dst as the src for the reply.  Otherwise (broadcast
613	 * or anonymous), use the address which corresponds
614	 * to the incoming interface.
615	 */
616	LIST_FOREACH(ia, INADDR_HASH(t.s_addr), ia_hash)
617		if (t.s_addr == IA_SIN(ia)->sin_addr.s_addr)
618			goto match;
619	if (m->m_pkthdr.rcvif != NULL &&
620	    m->m_pkthdr.rcvif->if_flags & IFF_BROADCAST) {
621		TAILQ_FOREACH(ifa, &m->m_pkthdr.rcvif->if_addrhead, ifa_link) {
622			if (ifa->ifa_addr->sa_family != AF_INET)
623				continue;
624			ia = ifatoia(ifa);
625			if (satosin(&ia->ia_broadaddr)->sin_addr.s_addr ==
626			    t.s_addr)
627				goto match;
628		}
629	}
630	ia = ip_rtaddr(ip->ip_dst, ro);
631	/* We need a route to do anything useful. */
632	if (ia == NULL) {
633		m_freem(m);
634		icmpstat.icps_noroute++;
635		goto done;
636	}
637match:
638	t = IA_SIN(ia)->sin_addr;
639	ip->ip_src = t;
640	ip->ip_ttl = ip_defttl;
641
642	if (optlen > 0) {
643		register u_char *cp;
644		int opt, cnt;
645		u_int len;
646
647		/*
648		 * Retrieve any source routing from the incoming packet;
649		 * add on any record-route or timestamp options.
650		 */
651		cp = (u_char *) (ip + 1);
652		if ((opts = ip_srcroute()) == 0 &&
653		    (opts = m_gethdr(M_DONTWAIT, MT_HEADER))) {
654			opts->m_len = sizeof(struct in_addr);
655			mtod(opts, struct in_addr *)->s_addr = 0;
656		}
657		if (opts) {
658#ifdef ICMPPRINTFS
659		    if (icmpprintfs)
660			    printf("icmp_reflect optlen %d rt %d => ",
661				optlen, opts->m_len);
662#endif
663		    for (cnt = optlen; cnt > 0; cnt -= len, cp += len) {
664			    opt = cp[IPOPT_OPTVAL];
665			    if (opt == IPOPT_EOL)
666				    break;
667			    if (opt == IPOPT_NOP)
668				    len = 1;
669			    else {
670				    if (cnt < IPOPT_OLEN + sizeof(*cp))
671					    break;
672				    len = cp[IPOPT_OLEN];
673				    if (len < IPOPT_OLEN + sizeof(*cp) ||
674				        len > cnt)
675					    break;
676			    }
677			    /*
678			     * Should check for overflow, but it "can't happen"
679			     */
680			    if (opt == IPOPT_RR || opt == IPOPT_TS ||
681				opt == IPOPT_SECURITY) {
682				    bcopy((caddr_t)cp,
683					mtod(opts, caddr_t) + opts->m_len, len);
684				    opts->m_len += len;
685			    }
686		    }
687		    /* Terminate & pad, if necessary */
688		    cnt = opts->m_len % 4;
689		    if (cnt) {
690			    for (; cnt < 4; cnt++) {
691				    *(mtod(opts, caddr_t) + opts->m_len) =
692					IPOPT_EOL;
693				    opts->m_len++;
694			    }
695		    }
696#ifdef ICMPPRINTFS
697		    if (icmpprintfs)
698			    printf("%d\n", opts->m_len);
699#endif
700		}
701		/*
702		 * Now strip out original options by copying rest of first
703		 * mbuf's data back, and adjust the IP length.
704		 */
705		ip->ip_len -= optlen;
706		ip->ip_vhl = IP_VHL_BORING;
707		m->m_len -= optlen;
708		if (m->m_flags & M_PKTHDR)
709			m->m_pkthdr.len -= optlen;
710		optlen += sizeof(struct ip);
711		bcopy((caddr_t)ip + optlen, (caddr_t)(ip + 1),
712			 (unsigned)(m->m_len - sizeof(struct ip)));
713	}
714	m->m_flags &= ~(M_BCAST|M_MCAST);
715	icmp_send(m, opts, ro);
716done:
717	if (opts)
718		(void)m_free(opts);
719	if (ro && ro->ro_rt)
720		RTFREE(ro->ro_rt);
721}
722
723/*
724 * Send an icmp packet back to the ip level,
725 * after supplying a checksum.
726 */
727static void
728icmp_send(m, opts, rt)
729	register struct mbuf *m;
730	struct mbuf *opts;
731	struct route *rt;
732{
733	register struct ip *ip = mtod(m, struct ip *);
734	register int hlen;
735	register struct icmp *icp;
736
737	hlen = IP_VHL_HL(ip->ip_vhl) << 2;
738	m->m_data += hlen;
739	m->m_len -= hlen;
740	icp = mtod(m, struct icmp *);
741	icp->icmp_cksum = 0;
742	icp->icmp_cksum = in_cksum(m, ip->ip_len - hlen);
743	m->m_data -= hlen;
744	m->m_len += hlen;
745	m->m_pkthdr.rcvif = (struct ifnet *)0;
746#ifdef ICMPPRINTFS
747	if (icmpprintfs) {
748		char buf[4 * sizeof "123"];
749		strcpy(buf, inet_ntoa(ip->ip_dst));
750		printf("icmp_send dst %s src %s\n",
751		       buf, inet_ntoa(ip->ip_src));
752	}
753#endif
754	(void) ip_output(m, opts, rt, 0, NULL, NULL);
755}
756
757n_time
758iptime()
759{
760	struct timeval atv;
761	u_long t;
762
763	getmicrotime(&atv);
764	t = (atv.tv_sec % (24*60*60)) * 1000 + atv.tv_usec / 1000;
765	return (htonl(t));
766}
767
768#if 1
769/*
770 * Return the next larger or smaller MTU plateau (table from RFC 1191)
771 * given current value MTU.  If DIR is less than zero, a larger plateau
772 * is returned; otherwise, a smaller value is returned.
773 */
774static int
775ip_next_mtu(mtu, dir)
776	int mtu;
777	int dir;
778{
779	static int mtutab[] = {
780		65535, 32000, 17914, 8166, 4352, 2002, 1492, 1006, 508, 296,
781		68, 0
782	};
783	int i;
784
785	for (i = 0; i < (sizeof mtutab) / (sizeof mtutab[0]); i++) {
786		if (mtu >= mtutab[i])
787			break;
788	}
789
790	if (dir < 0) {
791		if (i == 0) {
792			return 0;
793		} else {
794			return mtutab[i - 1];
795		}
796	} else {
797		if (mtutab[i] == 0) {
798			return 0;
799		} else if(mtu > mtutab[i]) {
800			return mtutab[i];
801		} else {
802			return mtutab[i + 1];
803		}
804	}
805}
806#endif
807
808
809/*
810 * badport_bandlim() - check for ICMP bandwidth limit
811 *
812 *	Return 0 if it is ok to send an ICMP error response, -1 if we have
813 *	hit our bandwidth limit and it is not ok.
814 *
815 *	If icmplim is <= 0, the feature is disabled and 0 is returned.
816 *
817 *	For now we separate the TCP and UDP subsystems w/ different 'which'
818 *	values.  We may eventually remove this separation (and simplify the
819 *	code further).
820 *
821 *	Note that the printing of the error message is delayed so we can
822 *	properly print the icmp error rate that the system was trying to do
823 *	(i.e. 22000/100 pps, etc...).  This can cause long delays in printing
824 *	the 'final' error, but it doesn't make sense to solve the printing
825 *	delay with more complex code.
826 */
827
828int
829badport_bandlim(int which)
830{
831	static int lticks[BANDLIM_MAX + 1];
832	static int lpackets[BANDLIM_MAX + 1];
833	int dticks;
834	const char *bandlimittype[] = {
835		"Limiting icmp unreach response",
836		"Limiting icmp ping response",
837		"Limiting icmp tstamp response",
838		"Limiting closed port RST response",
839		"Limiting open port RST response"
840		};
841
842	/*
843	 * Return ok status if feature disabled or argument out of
844	 * ranage.
845	 */
846
847	if (icmplim <= 0 || which > BANDLIM_MAX || which < 0)
848		return(0);
849	dticks = ticks - lticks[which];
850
851	/*
852	 * reset stats when cumulative dt exceeds one second.
853	 */
854
855	if ((unsigned int)dticks > hz) {
856		if (lpackets[which] > icmplim && icmplim_output) {
857			printf("%s from %d to %d packets per second\n",
858				bandlimittype[which],
859				lpackets[which],
860				icmplim
861			);
862		}
863		lticks[which] = ticks;
864		lpackets[which] = 0;
865	}
866
867	/*
868	 * bump packet count
869	 */
870
871	if (++lpackets[which] > icmplim) {
872		return(-1);
873	}
874	return(0);
875}
876
877