xref: /dragonfly/sys/netinet/ip_icmp.c (revision 55f88487)
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. Neither the name of the University nor the names of its contributors
14  *    may be used to endorse or promote products derived from this software
15  *    without specific prior written permission.
16  *
17  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
18  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
21  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
22  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
23  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
24  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
26  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
27  * SUCH DAMAGE.
28  *
29  *	@(#)ip_icmp.c	8.2 (Berkeley) 1/4/94
30  * $FreeBSD: src/sys/netinet/ip_icmp.c,v 1.39.2.19 2003/01/24 05:11:34 sam Exp $
31  */
32 
33 #include "opt_icmpprintfs.h"
34 
35 #include <sys/param.h>
36 #include <sys/systm.h>
37 #include <sys/malloc.h>	/* for M_NOWAIT */
38 #include <sys/mbuf.h>
39 #include <sys/protosw.h>
40 #include <sys/socket.h>
41 #include <sys/socketops.h>
42 #include <sys/time.h>
43 #include <sys/kernel.h>
44 #include <sys/sysctl.h>
45 #include <sys/in_cksum.h>
46 
47 #include <machine/stdarg.h>
48 
49 #include <net/if.h>
50 #include <net/if_types.h>
51 #include <net/netisr2.h>
52 #include <net/netmsg2.h>
53 #include <net/route.h>
54 
55 #define _IP_VHL
56 #include <netinet/in.h>
57 #include <netinet/in_systm.h>
58 #include <netinet/in_var.h>
59 #include <netinet/ip.h>
60 #include <netinet/ip_icmp.h>
61 #include <netinet/ip_var.h>
62 #include <netinet/icmp_var.h>
63 
64 /*
65  * ICMP routines: error generation, receive packet processing, and
66  * routines to turnaround packets back to the originator, and
67  * host table maintenance routines.
68  */
69 
70 struct icmpstat icmpstat;
71 SYSCTL_STRUCT(_net_inet_icmp, ICMPCTL_STATS, stats, CTLFLAG_RW,
72 	&icmpstat, icmpstat, "ICMP statistics");
73 
74 static int	icmpmaskrepl = 0;
75 SYSCTL_INT(_net_inet_icmp, ICMPCTL_MASKREPL, maskrepl, CTLFLAG_RW,
76 	&icmpmaskrepl, 0, "Allow replies to netmask requests");
77 
78 static int	drop_redirect = 0;
79 SYSCTL_INT(_net_inet_icmp, OID_AUTO, drop_redirect, CTLFLAG_RW,
80 	&drop_redirect, 0, "Ignore ICMP redirects");
81 
82 static int	log_redirect = 0;
83 SYSCTL_INT(_net_inet_icmp, OID_AUTO, log_redirect, CTLFLAG_RW,
84 	&log_redirect, 0, "Enable output about ICMP redirects");
85 
86 static int	discard_sourcequench = 1;
87 SYSCTL_INT(_net_inet_icmp, OID_AUTO, discard_sourcequench, CTLFLAG_RW,
88 	&discard_sourcequench, 0, "Discard ICMP Source Quench");
89 
90 #ifdef ICMP_BANDLIM
91 
92 /*
93  * ICMP error-response bandwidth limiting sysctl.  If not enabled, sysctl
94  *      variable content is -1 and read-only.
95  */
96 
97 static int      icmplim = 200;
98 SYSCTL_INT(_net_inet_icmp, ICMPCTL_ICMPLIM, icmplim, CTLFLAG_RW,
99 	&icmplim, 0, "ICMP bandwidth limit");
100 #else
101 
102 static int      icmplim = -1;
103 SYSCTL_INT(_net_inet_icmp, ICMPCTL_ICMPLIM, icmplim, CTLFLAG_RD,
104 	&icmplim, 0, "ICMP bandwidth limit");
105 
106 #endif
107 
108 static int	icmplim_output = 0;
109 SYSCTL_INT(_net_inet_icmp, OID_AUTO, icmplim_output, CTLFLAG_RW,
110 	&icmplim_output, 0, "Enable output about ICMP bandwidth limits");
111 
112 /*
113  * ICMP broadcast echo sysctl
114  */
115 
116 static int	icmpbmcastecho = 0;
117 SYSCTL_INT(_net_inet_icmp, OID_AUTO, bmcastecho, CTLFLAG_RW,
118     &icmpbmcastecho, 0, "");
119 
120 static char	icmp_reply_src[IFNAMSIZ];
121 SYSCTL_STRING(_net_inet_icmp, OID_AUTO, reply_src, CTLFLAG_RW,
122 	icmp_reply_src, IFNAMSIZ, "icmp reply source for non-local packets.");
123 
124 static int	icmp_rfi;
125 SYSCTL_INT(_net_inet_icmp, OID_AUTO, reply_from_interface, CTLFLAG_RW,
126 	&icmp_rfi, 0, "ICMP reply from incoming interface for "
127 	"non-local packets");
128 
129 #ifdef ICMPPRINTFS
130 static int	icmpprintfs = 0;
131 SYSCTL_INT(_net_inet_icmp, OID_AUTO, debug_prints, CTLFLAG_RW,
132 	&icmpprintfs, 0, "extra ICMP debug prints");
133 #endif
134 
135 static void	icmp_reflect (struct mbuf *);
136 static void	icmp_send (struct mbuf *, struct mbuf *, struct route *);
137 
138 extern	struct protosw inetsw[];
139 
140 /*
141  * Generate an error packet of type error
142  * in response to bad packet ip.
143  */
144 void
145 icmp_error(struct mbuf *n, int type, int code, n_long dest, int destmtu)
146 {
147 	struct ip *oip = mtod(n, struct ip *), *nip;
148 	unsigned oiplen = IP_VHL_HL(oip->ip_vhl) << 2;
149 	struct icmp *icp;
150 	struct mbuf *m;
151 	unsigned icmplen;
152 
153 #ifdef ICMPPRINTFS
154 	if (icmpprintfs)
155 		kprintf("icmp_error(%p, %d, %d)\n", oip, type, code);
156 #endif
157 	if (type != ICMP_REDIRECT)
158 		icmpstat.icps_error++;
159 	/*
160 	 * Don't send error if the original packet was encrypted.
161 	 * Don't send error if not the first fragment of message.
162 	 * Don't error if the old packet protocol was ICMP
163 	 * error message, only known informational types.
164 	 */
165 	if (n->m_flags & M_DECRYPTED)
166 		goto freeit;
167 	if (oip->ip_off &~ (IP_MF|IP_DF))
168 		goto freeit;
169 	if (oip->ip_p == IPPROTO_ICMP && type != ICMP_REDIRECT &&
170 	  n->m_len >= oiplen + ICMP_MINLEN &&
171 	  !ICMP_INFOTYPE(((struct icmp *)((caddr_t)oip + oiplen))->icmp_type)) {
172 		icmpstat.icps_oldicmp++;
173 		goto freeit;
174 	}
175 	/* Don't send error in response to a multicast or broadcast packet */
176 	if (n->m_flags & (M_BCAST|M_MCAST))
177 		goto freeit;
178 	/*
179 	 * First, formulate icmp message
180 	 */
181 	m = m_gethdr(M_NOWAIT, MT_HEADER);
182 	if (m == NULL)
183 		goto freeit;
184 	icmplen = min(oiplen + 8, oip->ip_len);
185 	if (icmplen < sizeof(struct ip))
186 		panic("icmp_error: bad length");
187 	m->m_len = icmplen + ICMP_MINLEN;
188 	MH_ALIGN(m, m->m_len);
189 	icp = mtod(m, struct icmp *);
190 	if ((u_int)type > ICMP_MAXTYPE)
191 		panic("icmp_error");
192 	icmpstat.icps_outhist[type]++;
193 	icp->icmp_type = type;
194 	if (type == ICMP_REDIRECT)
195 		icp->icmp_gwaddr.s_addr = dest;
196 	else {
197 		icp->icmp_void = 0;
198 		/*
199 		 * The following assignments assume an overlay with the
200 		 * zeroed icmp_void field.
201 		 */
202 		if (type == ICMP_PARAMPROB) {
203 			icp->icmp_pptr = code;
204 			code = 0;
205 		} else if (type == ICMP_UNREACH &&
206 			code == ICMP_UNREACH_NEEDFRAG && destmtu) {
207 			icp->icmp_nextmtu = htons(destmtu);
208 		}
209 	}
210 
211 	icp->icmp_code = code;
212 	m_copydata(n, 0, icmplen, (caddr_t)&icp->icmp_ip);
213 	nip = &icp->icmp_ip;
214 
215 	/*
216 	 * Convert fields to network representation.
217 	 */
218 	nip->ip_len = htons(nip->ip_len);
219 	nip->ip_off = htons(nip->ip_off);
220 
221 	/*
222 	 * Now, copy old ip header (without options)
223 	 * in front of icmp message.
224 	 */
225 	if (m->m_data - sizeof(struct ip) < m->m_pktdat)
226 		panic("icmp len");
227 	m->m_data -= sizeof(struct ip);
228 	m->m_len += sizeof(struct ip);
229 	m->m_pkthdr.len = m->m_len;
230 	m->m_pkthdr.rcvif = n->m_pkthdr.rcvif;
231 	nip = mtod(m, struct ip *);
232 	bcopy(oip, nip, sizeof(struct ip));
233 	nip->ip_len = m->m_len;
234 	nip->ip_vhl = IP_VHL_BORING;
235 	nip->ip_p = IPPROTO_ICMP;
236 	nip->ip_tos = 0;
237 	m->m_pkthdr.fw_flags |= n->m_pkthdr.fw_flags & FW_MBUF_GENERATED;
238 	icmp_reflect(m);
239 
240 freeit:
241 	m_freem(n);
242 }
243 
244 static void
245 icmp_ctlinput_done_handler(netmsg_t nmsg)
246 {
247 	struct netmsg_ctlinput *msg = (struct netmsg_ctlinput *)nmsg;
248 	struct mbuf *m = msg->m;
249 	int hlen = msg->hlen;
250 
251 	rip_input(&m, &hlen, msg->proto);
252 }
253 
254 static void
255 icmp_ctlinput_done(struct mbuf *m)
256 {
257 	struct netmsg_ctlinput *msg = &m->m_hdr.mh_ctlmsg;
258 
259 	netmsg_init(&msg->base, NULL, &netisr_apanic_rport, 0,
260 	    icmp_ctlinput_done_handler);
261 	lwkt_sendmsg(netisr_cpuport(0), &msg->base.lmsg);
262 }
263 
264 static void
265 icmp_mtudisc(struct mbuf *m, int hlen)
266 {
267 	struct sockaddr_in icmpsrc = { sizeof(struct sockaddr_in), AF_INET };
268 	struct rtentry *rt;
269 	struct icmp *icp;
270 
271 	KASSERT(curthread->td_type == TD_TYPE_NETISR, ("not in netisr"));
272 
273 	icp = mtodoff(m, struct icmp *, hlen);
274 	icmpsrc.sin_addr = icp->icmp_ip.ip_dst;
275 
276 	/*
277 	 * MTU discovery:
278 	 * If we got a needfrag and there is a host route to the original
279 	 * destination, and the MTU is not locked, then set the MTU in the
280 	 * route to the suggested new value (if given) and then notify as
281 	 * usual.  The ULPs will notice that the MTU has changed and adapt
282 	 * accordingly.  If no new MTU was suggested, then we guess a new
283 	 * one less than the current value.  If the new MTU is unreasonably
284 	 * small (arbitrarily set at 296), then we reset the MTU to the
285 	 * interface value and enable the lock bit, indicating that we are
286 	 * no longer doing MTU discovery.
287 	 */
288 	rt = rtpurelookup((struct sockaddr *)&icmpsrc);
289 	if (rt != NULL && (rt->rt_flags & RTF_HOST) &&
290 	    !(rt->rt_rmx.rmx_locks & RTV_MTU)) {
291 #ifdef DEBUG_MTUDISC
292 		char src_buf[INET_ADDRSTRLEN];
293 #endif
294 		int mtu;
295 
296 		mtu = ntohs(icp->icmp_nextmtu);
297 		if (!mtu)
298 			mtu = ip_next_mtu(rt->rt_rmx.rmx_mtu, 1);
299 #ifdef DEBUG_MTUDISC
300 		kprintf("MTU for %s reduced to %d\n",
301 		    inet_ntop(AF_INET, &icmpsrc.sin_addr,
302 			src_buf, INET_ADDRSTRLEN), mtu);
303 #endif
304 		if (mtu < 296) {
305 			/* rt->rt_rmx.rmx_mtu = rt->rt_ifp->if_mtu; */
306 			rt->rt_rmx.rmx_locks |= RTV_MTU;
307 		} else if (rt->rt_rmx.rmx_mtu > mtu) {
308 			rt->rt_rmx.rmx_mtu = mtu;
309 		}
310 	}
311 	if (rt != NULL)
312 		--rt->rt_refcnt;
313 
314 	/*
315 	 * XXX if the packet contains [IPv4 AH TCP], we can't make a
316 	 * notification to TCP layer.
317 	 */
318 	so_pr_ctlinput_direct(&inetsw[ip_protox[icp->icmp_ip.ip_p]],
319 	    PRC_MSGSIZE, (struct sockaddr *)&icmpsrc, &icp->icmp_ip);
320 }
321 
322 static void
323 icmp_mtudisc_handler(netmsg_t nmsg)
324 {
325 	struct netmsg_ctlinput *msg = (struct netmsg_ctlinput *)nmsg;
326 	int nextcpu;
327 
328 	ASSERT_NETISR_NCPUS(mycpuid);
329 
330 	icmp_mtudisc(msg->m, msg->hlen);
331 
332 	nextcpu = mycpuid + 1;
333 	if (nextcpu < netisr_ncpus)
334 		lwkt_forwardmsg(netisr_cpuport(nextcpu), &msg->base.lmsg);
335 	else
336 		icmp_ctlinput_done(msg->m);
337 }
338 
339 static boolean_t
340 icmp_mtudisc_start(struct mbuf *m, int hlen, int proto)
341 {
342 	struct netmsg_ctlinput *msg;
343 
344 	ASSERT_NETISR0;
345 
346 	icmp_mtudisc(m, hlen);
347 
348 	if (netisr_ncpus == 1) {
349 		/* There is only one netisr; done */
350 		return FALSE;
351 	}
352 
353 	msg = &m->m_hdr.mh_ctlmsg;
354 	netmsg_init(&msg->base, NULL, &netisr_apanic_rport, 0,
355 	    icmp_mtudisc_handler);
356 	msg->m = m;
357 	msg->cmd = PRC_MSGSIZE;
358 	msg->hlen = hlen;
359 	msg->proto = proto;
360 
361 	lwkt_sendmsg(netisr_cpuport(1), &msg->base.lmsg);
362 	return TRUE;
363 }
364 
365 static void
366 icmp_ctlinput(struct mbuf *m, int cmd, int hlen)
367 {
368 	struct sockaddr_in icmpsrc = { sizeof(struct sockaddr_in), AF_INET };
369 	struct icmp *icp;
370 
371 	KASSERT(curthread->td_type == TD_TYPE_NETISR, ("not in netisr"));
372 
373 	icp = mtodoff(m, struct icmp *, hlen);
374 	icmpsrc.sin_addr = icp->icmp_ip.ip_dst;
375 
376 	/*
377 	 * XXX if the packet contains [IPv4 AH TCP], we can't make a
378 	 * notification to TCP layer.
379 	 */
380 	so_pr_ctlinput_direct(&inetsw[ip_protox[icp->icmp_ip.ip_p]],
381 	    cmd, (struct sockaddr *)&icmpsrc, &icp->icmp_ip);
382 }
383 
384 static void
385 icmp_ctlinput_handler(netmsg_t nmsg)
386 {
387 	struct netmsg_ctlinput *msg = (struct netmsg_ctlinput *)nmsg;
388 
389 	ASSERT_NETISR_NCPUS(mycpuid);
390 
391 	icmp_ctlinput(msg->m, msg->cmd, msg->hlen);
392 	icmp_ctlinput_done(msg->m);
393 }
394 
395 static void
396 icmp_ctlinput_start(struct mbuf *m, struct lwkt_port *port,
397     int cmd, int hlen, int proto)
398 {
399 	struct netmsg_ctlinput *msg;
400 
401 	KASSERT(&curthread->td_msgport != port,
402 	    ("send icmp ctlinput to the current netisr"));
403 
404 	msg = &m->m_hdr.mh_ctlmsg;
405 	netmsg_init(&msg->base, NULL, &netisr_apanic_rport, 0,
406 	    icmp_ctlinput_handler);
407 	msg->m = m;
408 	msg->cmd = cmd;
409 	msg->hlen = hlen;
410 	msg->proto = proto;
411 
412 	lwkt_sendmsg(port, &msg->base.lmsg);
413 }
414 
415 static void
416 icmp_ctlinput_global_handler(netmsg_t nmsg)
417 {
418 	struct netmsg_ctlinput *msg = (struct netmsg_ctlinput *)nmsg;
419 	int nextcpu;
420 
421 	ASSERT_NETISR_NCPUS(mycpuid);
422 
423 	icmp_ctlinput(msg->m, msg->cmd, msg->hlen);
424 
425 	nextcpu = mycpuid + 1;
426 	if (nextcpu < netisr_ncpus)
427 		lwkt_forwardmsg(netisr_cpuport(nextcpu), &msg->base.lmsg);
428 	else
429 		icmp_ctlinput_done(msg->m);
430 }
431 
432 static void
433 icmp_ctlinput_global_start(struct mbuf *m, int cmd, int hlen, int proto)
434 {
435 	struct netmsg_ctlinput *msg;
436 
437 	ASSERT_NETISR0;
438 	KASSERT(netisr_ncpus > 1, ("there is only 1 netisr cpu"));
439 
440 	icmp_ctlinput(m, cmd, hlen);
441 
442 	msg = &m->m_hdr.mh_ctlmsg;
443 	netmsg_init(&msg->base, NULL, &netisr_apanic_rport, 0,
444 	    icmp_ctlinput_global_handler);
445 	msg->m = m;
446 	msg->cmd = cmd;
447 	msg->hlen = hlen;
448 	msg->proto = proto;
449 
450 	lwkt_sendmsg(netisr_cpuport(1), &msg->base.lmsg);
451 }
452 
453 #define ICMP_RTREDIRECT_FLAGS	(RTF_GATEWAY | RTF_HOST)
454 
455 static void
456 icmp_redirect(struct mbuf *m, int hlen, boolean_t prt)
457 {
458 	struct sockaddr_in icmpsrc = { sizeof(struct sockaddr_in), AF_INET };
459 	struct sockaddr_in icmpdst = { sizeof(struct sockaddr_in), AF_INET };
460 	struct sockaddr_in icmpgw = { sizeof(struct sockaddr_in), AF_INET };
461 	struct icmp *icp;
462 	struct ip *ip;
463 
464 	KASSERT(curthread->td_type == TD_TYPE_NETISR, ("not in netisr"));
465 
466 	ip = mtod(m, struct ip *);
467 	icp = mtodoff(m, struct icmp *, hlen);
468 
469 	/*
470 	 * Short circuit routing redirects to force immediate change
471 	 * in the kernel's routing tables.  The message is also handed
472 	 * to anyone listening on a raw socket (e.g. the routing daemon
473 	 * for use in updating its tables).
474 	 */
475 #ifdef ICMPPRINTFS
476 	if (icmpprintfs && prt) {
477 		char dst_buf[INET_ADDRSTRLEN], gw_buf[INET_ADDRSTRLEN];
478 
479 		kprintf("redirect dst %s to %s\n",
480 		    inet_ntop(AF_INET, &icp->icmp_ip.ip_dst,
481 			dst_buf, INET_ADDRSTRLEN),
482 		    inet_ntop(AF_INET, &icp->icmp_gwaddr,
483 			gw_buf, INET_ADDRSTRLEN));
484 	}
485 #endif
486 	icmpgw.sin_addr = ip->ip_src;
487 	icmpdst.sin_addr = icp->icmp_gwaddr;
488 	icmpsrc.sin_addr = icp->icmp_ip.ip_dst;
489 	rtredirect_oncpu((struct sockaddr *)&icmpsrc,
490 	    (struct sockaddr *)&icmpdst, NULL, ICMP_RTREDIRECT_FLAGS,
491 	    (struct sockaddr *)&icmpgw);
492 	kpfctlinput_direct(PRC_REDIRECT_HOST, (struct sockaddr *)&icmpsrc);
493 }
494 
495 static void
496 icmp_redirect_done_handler(netmsg_t nmsg)
497 {
498 	struct netmsg_ctlinput *msg = (struct netmsg_ctlinput *)nmsg;
499 	struct mbuf *m = msg->m;
500 	int hlen = msg->hlen;
501 
502 	rip_input(&m, &hlen, msg->proto);
503 }
504 
505 static void
506 icmp_redirect_done(struct mbuf *m, int hlen, boolean_t dispatch_rip)
507 {
508 	struct rt_addrinfo rtinfo;
509 	struct sockaddr_in icmpsrc = { sizeof(struct sockaddr_in), AF_INET };
510 	struct sockaddr_in icmpdst = { sizeof(struct sockaddr_in), AF_INET };
511 	struct sockaddr_in icmpgw = { sizeof(struct sockaddr_in), AF_INET };
512 	struct icmp *icp;
513 	struct ip *ip;
514 
515 	ip = mtod(m, struct ip *);
516 	icp = mtodoff(m, struct icmp *, hlen);
517 
518 	icmpgw.sin_addr = ip->ip_src;
519 	icmpdst.sin_addr = icp->icmp_gwaddr;
520 	icmpsrc.sin_addr = icp->icmp_ip.ip_dst;
521 
522 	bzero(&rtinfo, sizeof(struct rt_addrinfo));
523 	rtinfo.rti_info[RTAX_DST] = (struct sockaddr *)&icmpsrc;
524 	rtinfo.rti_info[RTAX_GATEWAY] = (struct sockaddr *)&icmpdst;
525 	rtinfo.rti_info[RTAX_NETMASK] = NULL;
526 	rtinfo.rti_info[RTAX_AUTHOR] = (struct sockaddr *)&icmpgw;
527 	rt_missmsg(RTM_REDIRECT, &rtinfo, ICMP_RTREDIRECT_FLAGS, 0);
528 
529 	if (dispatch_rip) {
530 		struct netmsg_ctlinput *msg = &m->m_hdr.mh_ctlmsg;
531 
532 		netmsg_init(&msg->base, NULL, &netisr_apanic_rport, 0,
533 		    icmp_redirect_done_handler);
534 		lwkt_sendmsg(netisr_cpuport(0), &msg->base.lmsg);
535 	}
536 }
537 
538 static void
539 icmp_redirect_handler(netmsg_t nmsg)
540 {
541 	struct netmsg_ctlinput *msg = (struct netmsg_ctlinput *)nmsg;
542 	int nextcpu;
543 
544 	ASSERT_NETISR_NCPUS(mycpuid);
545 
546 	icmp_redirect(msg->m, msg->hlen, FALSE);
547 
548 	nextcpu = mycpuid + 1;
549 	if (nextcpu < netisr_ncpus)
550 		lwkt_forwardmsg(netisr_cpuport(nextcpu), &msg->base.lmsg);
551 	else
552 		icmp_redirect_done(msg->m, msg->hlen, TRUE);
553 }
554 
555 static boolean_t
556 icmp_redirect_start(struct mbuf *m, int hlen, int proto)
557 {
558 	struct netmsg_ctlinput *msg;
559 
560 	ASSERT_NETISR0;
561 
562 	icmp_redirect(m, hlen, TRUE);
563 
564 	if (netisr_ncpus == 1) {
565 		/* There is only one netisr; done */
566 		icmp_redirect_done(m, hlen, FALSE);
567 		return FALSE;
568 	}
569 
570 	msg = &m->m_hdr.mh_ctlmsg;
571 	netmsg_init(&msg->base, NULL, &netisr_apanic_rport, 0,
572 	    icmp_redirect_handler);
573 	msg->m = m;
574 	msg->cmd = PRC_REDIRECT_HOST;
575 	msg->hlen = hlen;
576 	msg->proto = proto;
577 
578 	lwkt_sendmsg(netisr_cpuport(1), &msg->base.lmsg);
579 	return TRUE;
580 }
581 
582 /*
583  * Process a received ICMP message.
584  */
585 int
586 icmp_input(struct mbuf **mp, int *offp, int proto)
587 {
588 	struct sockaddr_in icmpsrc = { sizeof(struct sockaddr_in), AF_INET };
589 	struct sockaddr_in icmpdst = { sizeof(struct sockaddr_in), AF_INET };
590 	struct icmp *icp;
591 	struct in_ifaddr *ia;
592 	struct mbuf *m = *mp;
593 	struct ip *ip = mtod(m, struct ip *);
594 	int icmplen = ip->ip_len;
595 	int i, hlen;
596 	int code;
597 
598 	ASSERT_NETISR0;
599 
600 	*mp = NULL;
601 	hlen = *offp;
602 
603 	/*
604 	 * Locate icmp structure in mbuf, and check
605 	 * that not corrupted and of at least minimum length.
606 	 */
607 #ifdef ICMPPRINTFS
608 	if (icmpprintfs) {
609 		char src_buf[INET_ADDRSTRLEN], dst_buf[INET_ADDRSTRLEN];
610 
611 		kprintf("icmp_input from %s to %s, len %d\n",
612 		    inet_ntop(AF_INET, &ip->ip_src, src_buf, INET_ADDRSTRLEN),
613 		    inet_ntop(AF_INET, &ip->ip_dst, dst_buf, INET_ADDRSTRLEN),
614 		    icmplen);
615 	}
616 #endif
617 	if (icmplen < ICMP_MINLEN) {
618 		icmpstat.icps_tooshort++;
619 		goto freeit;
620 	}
621 	i = hlen + min(icmplen, ICMP_ADVLENMIN);
622 	if (m->m_len < i && (m = m_pullup(m, i)) == NULL)  {
623 		icmpstat.icps_tooshort++;
624 		return(IPPROTO_DONE);
625 	}
626 	ip = mtod(m, struct ip *);
627 
628 	if (in_cksum_skip(m, hlen + icmplen, hlen)) {
629 		icmpstat.icps_checksum++;
630 		goto freeit;
631 	}
632 	icp = (struct icmp *)((caddr_t)ip + hlen);
633 
634 #ifdef ICMPPRINTFS
635 	if (icmpprintfs)
636 		kprintf("icmp_input, type %d code %d\n", icp->icmp_type,
637 		    icp->icmp_code);
638 #endif
639 
640 	/*
641 	 * Message type specific processing.
642 	 */
643 	if (icp->icmp_type > ICMP_MAXTYPE)
644 		goto raw;
645 	icmpstat.icps_inhist[icp->icmp_type]++;
646 	code = icp->icmp_code;
647 	switch (icp->icmp_type) {
648 
649 	case ICMP_UNREACH:
650 		switch (code) {
651 			case ICMP_UNREACH_NET:
652 			case ICMP_UNREACH_HOST:
653 			case ICMP_UNREACH_SRCFAIL:
654 			case ICMP_UNREACH_NET_UNKNOWN:
655 			case ICMP_UNREACH_HOST_UNKNOWN:
656 			case ICMP_UNREACH_ISOLATED:
657 			case ICMP_UNREACH_TOSNET:
658 			case ICMP_UNREACH_TOSHOST:
659 			case ICMP_UNREACH_HOST_PRECEDENCE:
660 			case ICMP_UNREACH_PRECEDENCE_CUTOFF:
661 				code = PRC_UNREACH_NET;
662 				break;
663 
664 			case ICMP_UNREACH_NEEDFRAG:
665 				code = PRC_MSGSIZE;
666 				break;
667 
668 			/*
669 			 * RFC 1122, Sections 3.2.2.1 and 4.2.3.9.
670 			 * Treat subcodes 2,3 as immediate RST
671 			 */
672 			case ICMP_UNREACH_PROTOCOL:
673 			case ICMP_UNREACH_PORT:
674 				code = PRC_UNREACH_PORT;
675 				break;
676 
677 			case ICMP_UNREACH_NET_PROHIB:
678 			case ICMP_UNREACH_HOST_PROHIB:
679 			case ICMP_UNREACH_FILTER_PROHIB:
680 				code = PRC_UNREACH_ADMIN_PROHIB;
681 				break;
682 
683 			default:
684 				goto badcode;
685 		}
686 		goto deliver;
687 
688 	case ICMP_TIMXCEED:
689 		if (code > 1)
690 			goto badcode;
691 		code += PRC_TIMXCEED_INTRANS;
692 		goto deliver;
693 
694 	case ICMP_PARAMPROB:
695 		if (code > 1)
696 			goto badcode;
697 		code = PRC_PARAMPROB;
698 		goto deliver;
699 
700 	case ICMP_SOURCEQUENCH:
701 		if (code)
702 			goto badcode;
703 		if (discard_sourcequench)
704 			break;
705 		code = PRC_QUENCH;
706 deliver:
707 		/*
708 		 * Problem with datagram; advise higher level routines.
709 		 */
710 		if (icmplen < ICMP_ADVLENMIN || icmplen < ICMP_ADVLEN(icp) ||
711 		    IP_VHL_HL(icp->icmp_ip.ip_vhl) < (sizeof(struct ip) >> 2)) {
712 			icmpstat.icps_badlen++;
713 			goto freeit;
714 		}
715 		/* Discard ICMP's in response to multicast packets */
716 		if (IN_MULTICAST(ntohl(icp->icmp_ip.ip_dst.s_addr)))
717 			goto badcode;
718 #ifdef ICMPPRINTFS
719 		if (icmpprintfs)
720 			kprintf("deliver to protocol %d\n", icp->icmp_ip.ip_p);
721 #endif
722 		icmpsrc.sin_addr = icp->icmp_ip.ip_dst;
723 
724 		/*
725 		 * MTU discovery
726 		 */
727 		if (code == PRC_MSGSIZE) {
728 			/* Run MTU discovery in all netisrs */
729 			if (icmp_mtudisc_start(m, hlen, proto)) {
730 				/* Forwarded; done */
731 				return IPPROTO_DONE;
732 			}
733 			/* Move on; run rip_input() directly */
734 		} else {
735 			struct protosw *pr;
736 			struct lwkt_port *port;
737 			int cpu;
738 
739 			pr = &inetsw[ip_protox[icp->icmp_ip.ip_p]];
740 			port = so_pr_ctlport(pr, code,
741 			    (struct sockaddr *)&icmpsrc, &icp->icmp_ip, &cpu);
742 			if (port != NULL) {
743 				if (cpu == netisr_ncpus) {
744 					if (netisr_ncpus > 1) {
745 						/*
746 						 * Run pr_ctlinput in all
747 						 * netisrs
748 						 */
749 						icmp_ctlinput_global_start(m,
750 						    code, hlen, proto);
751 						return IPPROTO_DONE;
752 					}
753 					/*
754 					 * There is only one netisr; run
755 					 * pr_ctlinput directly.
756 					 */
757 				} else if (cpu != mycpuid) {
758 					/*
759 					 * Send to the target netisr to run
760 					 * pr_ctlinput.
761 					 */
762 					icmp_ctlinput_start(m, port,
763 					    code, hlen, proto);
764 					return IPPROTO_DONE;
765 				}
766 
767 				/*
768 				 * The target netisr is this netisr.
769 				 *
770 				 * XXX if the packet contains [IPv4 AH TCP],
771 				 * we can't make a notification to TCP layer.
772 				 */
773 				so_pr_ctlinput_direct(pr, code,
774 				    (struct sockaddr *)&icmpsrc, &icp->icmp_ip);
775 			}
776 			/* Move on; run rip_input() directly */
777 		}
778 		break;
779 badcode:
780 		icmpstat.icps_badcode++;
781 		break;
782 
783 	case ICMP_ECHO:
784 		if (!icmpbmcastecho
785 		    && (m->m_flags & (M_MCAST | M_BCAST)) != 0) {
786 			icmpstat.icps_bmcastecho++;
787 			break;
788 		}
789 		icp->icmp_type = ICMP_ECHOREPLY;
790 #ifdef ICMP_BANDLIM
791 		if (badport_bandlim(BANDLIM_ICMP_ECHO) < 0)
792 			goto freeit;
793 		else
794 #endif
795 			goto reflect;
796 
797 	case ICMP_TSTAMP:
798 		if (!icmpbmcastecho
799 		    && (m->m_flags & (M_MCAST | M_BCAST)) != 0) {
800 			icmpstat.icps_bmcasttstamp++;
801 			break;
802 		}
803 		if (icmplen < ICMP_TSLEN) {
804 			icmpstat.icps_badlen++;
805 			break;
806 		}
807 		icp->icmp_type = ICMP_TSTAMPREPLY;
808 		icp->icmp_rtime = iptime();
809 		icp->icmp_ttime = icp->icmp_rtime;	/* bogus, do later! */
810 #ifdef ICMP_BANDLIM
811 		if (badport_bandlim(BANDLIM_ICMP_TSTAMP) < 0)
812 			goto freeit;
813 		else
814 #endif
815 			goto reflect;
816 
817 	case ICMP_MASKREQ:
818 		if (icmpmaskrepl == 0)
819 			break;
820 		/*
821 		 * We are not able to respond with all ones broadcast
822 		 * unless we receive it over a point-to-point interface.
823 		 */
824 		if (icmplen < ICMP_MASKLEN)
825 			break;
826 		switch (ip->ip_dst.s_addr) {
827 
828 		case INADDR_BROADCAST:
829 		case INADDR_ANY:
830 			icmpdst.sin_addr = ip->ip_src;
831 			break;
832 
833 		default:
834 			icmpdst.sin_addr = ip->ip_dst;
835 		}
836 		ia = (struct in_ifaddr *)ifaof_ifpforaddr(
837 			    (struct sockaddr *)&icmpdst, m->m_pkthdr.rcvif);
838 		if (ia == NULL)
839 			break;
840 		if (ia->ia_ifp == 0)
841 			break;
842 		icp->icmp_type = ICMP_MASKREPLY;
843 		icp->icmp_mask = ia->ia_sockmask.sin_addr.s_addr;
844 		if (ip->ip_src.s_addr == 0) {
845 			if (ia->ia_ifp->if_flags & IFF_BROADCAST)
846 			    ip->ip_src = satosin(&ia->ia_broadaddr)->sin_addr;
847 			else if (ia->ia_ifp->if_flags & IFF_POINTOPOINT)
848 			    ip->ip_src = satosin(&ia->ia_dstaddr)->sin_addr;
849 		}
850 reflect:
851 		ip->ip_len += hlen;	/* since ip_input deducts this */
852 		icmpstat.icps_reflect++;
853 		icmpstat.icps_outhist[icp->icmp_type]++;
854 		icmp_reflect(m);
855 		return(IPPROTO_DONE);
856 
857 	case ICMP_REDIRECT:
858 		if (log_redirect) {
859 			char src_buf[INET_ADDRSTRLEN];
860 			char dst_buf[INET_ADDRSTRLEN];
861 			char gwy_buf[INET_ADDRSTRLEN];
862 
863 			kprintf("icmp redirect from %s: %s => %s\n",
864 			    inet_ntop(AF_INET, &ip->ip_src,
865 			        src_buf, INET_ADDRSTRLEN),
866 			    inet_ntop(AF_INET, &icp->icmp_ip.ip_dst,
867 			        dst_buf, INET_ADDRSTRLEN),
868 			    inet_ntop(AF_INET, &icp->icmp_gwaddr,
869 			        gwy_buf, INET_ADDRSTRLEN));
870 		}
871 		if (drop_redirect)
872 			break;
873 		if (code > 3)
874 			goto badcode;
875 		if (icmplen < ICMP_ADVLENMIN || icmplen < ICMP_ADVLEN(icp) ||
876 		    IP_VHL_HL(icp->icmp_ip.ip_vhl) < (sizeof(struct ip) >> 2)) {
877 			icmpstat.icps_badlen++;
878 			break;
879 		}
880 #ifdef ICMPPRINTFS
881 		if (icmpprintfs) {
882 			char dst_buf[INET_ADDRSTRLEN], gw_buf[INET_ADDRSTRLEN];
883 
884 			kprintf("redirect dst %s to %s\n",
885 			    inet_ntop(AF_INET, &icp->icmp_ip.ip_dst,
886 			        dst_buf, INET_ADDRSTRLEN),
887 			    inet_ntop(AF_INET, &icp->icmp_gwaddr,
888 			        gw_buf, INET_ADDRSTRLEN));
889 		}
890 #endif
891 		icmpsrc.sin_addr = icp->icmp_ip.ip_dst;
892 
893 		/* Run redirect in all netisrs */
894 		if (icmp_redirect_start(m, hlen, proto)) {
895 			/* Forwarded; done */
896 			return IPPROTO_DONE;
897 		}
898 		/* Move on; run rip_input() directly */
899 		break;
900 
901 	/*
902 	 * No kernel processing for the following;
903 	 * just fall through to send to raw listener.
904 	 */
905 	case ICMP_ECHOREPLY:
906 	case ICMP_ROUTERADVERT:
907 	case ICMP_ROUTERSOLICIT:
908 	case ICMP_TSTAMPREPLY:
909 	case ICMP_IREQREPLY:
910 	case ICMP_MASKREPLY:
911 	default:
912 		break;
913 	}
914 
915 raw:
916 	*mp = m;
917 	rip_input(mp, offp, proto);
918 	return(IPPROTO_DONE);
919 
920 freeit:
921 	m_freem(m);
922 	return(IPPROTO_DONE);
923 }
924 
925 /*
926  * Reflect the ip packet back to the source
927  */
928 static void
929 icmp_reflect(struct mbuf *m)
930 {
931 	struct ip *ip = mtod(m, struct ip *);
932 	struct in_ifaddr *ia;
933 	struct in_ifaddr_container *iac;
934 	struct ifaddr_container *ifac;
935 	struct ifnet *ifp;
936 	struct in_addr t;
937 	struct mbuf *opts = NULL;
938 	int optlen = (IP_VHL_HL(ip->ip_vhl) << 2) - sizeof(struct ip);
939 	struct route *ro = NULL, rt;
940 
941 	if (!in_canforward(ip->ip_src) &&
942 	    ((ntohl(ip->ip_src.s_addr) & IN_CLASSA_NET) !=
943 	     (IN_LOOPBACKNET << IN_CLASSA_NSHIFT))) {
944 		m_freem(m);	/* Bad return address */
945 		icmpstat.icps_badaddr++;
946 		goto done;	/* Ip_output() will check for broadcast */
947 	}
948 	t = ip->ip_dst;
949 	ip->ip_dst = ip->ip_src;
950 
951 	ro = &rt;
952 	bzero(ro, sizeof *ro);
953 
954 	/*
955 	 * If the incoming packet was addressed directly to us,
956 	 * use dst as the src for the reply.  Otherwise (broadcast
957 	 * or anonymous), use the address which corresponds
958 	 * to the incoming interface.
959 	 */
960 	ia = NULL;
961 	LIST_FOREACH(iac, INADDR_HASH(t.s_addr), ia_hash) {
962 		if (t.s_addr == IA_SIN(iac->ia)->sin_addr.s_addr) {
963 			ia = iac->ia;
964 			goto match;
965 		}
966 	}
967 	ifp = m->m_pkthdr.rcvif;
968 	if (ifp != NULL && (ifp->if_flags & IFF_BROADCAST)) {
969 		TAILQ_FOREACH(ifac, &ifp->if_addrheads[mycpuid], ifa_link) {
970 			struct ifaddr *ifa = ifac->ifa;
971 
972 			if (ifa->ifa_addr->sa_family != AF_INET)
973 				continue;
974 			ia = ifatoia(ifa);
975 			if (satosin(&ia->ia_broadaddr)->sin_addr.s_addr ==
976 			    t.s_addr)
977 				goto match;
978 		}
979 	}
980 	/*
981 	 * If the packet was transiting through us, use the address of
982 	 * the interface the packet came through in.  If that interface
983 	 * doesn't have a suitable IP address, the normal selection
984 	 * criteria apply.
985 	 */
986 	if (icmp_rfi && ifp != NULL) {
987 		TAILQ_FOREACH(ifac, &ifp->if_addrheads[mycpuid], ifa_link) {
988 			struct ifaddr *ifa = ifac->ifa;
989 
990 			if (ifa->ifa_addr->sa_family != AF_INET)
991 				continue;
992 			ia = ifatoia(ifa);
993 			goto match;
994 		}
995 	}
996 	/*
997 	 * If the incoming packet was not addressed directly to us, use
998 	 * designated interface for icmp replies specified by sysctl
999 	 * net.inet.icmp.reply_src (default not set). Otherwise continue
1000 	 * with normal source selection.
1001 	 */
1002 	if (icmp_reply_src[0] != '\0' &&
1003 	    (ifp = ifunit_netisr(icmp_reply_src))) {
1004 		TAILQ_FOREACH(ifac, &ifp->if_addrheads[mycpuid], ifa_link) {
1005 			struct ifaddr *ifa = ifac->ifa;
1006 
1007 			if (ifa->ifa_addr->sa_family != AF_INET)
1008 				continue;
1009 			ia = ifatoia(ifa);
1010 			goto match;
1011 		}
1012 	}
1013 	/*
1014 	 * If the packet was transiting through us, use the address of
1015 	 * the interface that is the closest to the packet source.
1016 	 * When we don't have a route back to the packet source, stop here
1017 	 * and drop the packet.
1018 	 */
1019 	ia = ip_rtaddr(ip->ip_dst, ro);
1020 	if (ia == NULL) {
1021 		m_freem(m);
1022 		icmpstat.icps_noroute++;
1023 		goto done;
1024 	}
1025 match:
1026 	t = IA_SIN(ia)->sin_addr;
1027 	ip->ip_src = t;
1028 	ip->ip_ttl = ip_defttl;
1029 
1030 	if (optlen > 0) {
1031 		u_char *cp;
1032 		int opt, cnt;
1033 		u_int len;
1034 
1035 		/*
1036 		 * Retrieve any source routing from the incoming packet;
1037 		 * add on any record-route or timestamp options.
1038 		 */
1039 		cp = (u_char *) (ip + 1);
1040 		if ((opts = ip_srcroute(m)) == NULL &&
1041 		    (opts = m_gethdr(M_NOWAIT, MT_HEADER))) {
1042 			opts->m_len = sizeof(struct in_addr);
1043 			mtod(opts, struct in_addr *)->s_addr = 0;
1044 		}
1045 		if (opts) {
1046 #ifdef ICMPPRINTFS
1047 			if (icmpprintfs)
1048 				kprintf("icmp_reflect optlen %d rt %d => ",
1049 				       optlen, opts->m_len);
1050 #endif
1051 			for (cnt = optlen; cnt > 0; cnt -= len, cp += len) {
1052 				opt = cp[IPOPT_OPTVAL];
1053 				if (opt == IPOPT_EOL)
1054 					break;
1055 				if (opt == IPOPT_NOP)
1056 					len = 1;
1057 				else {
1058 					if (cnt < IPOPT_OLEN + sizeof *cp)
1059 						break;
1060 					len = cp[IPOPT_OLEN];
1061 					if (len < IPOPT_OLEN + sizeof *cp ||
1062 					    len > cnt)
1063 					break;
1064 				}
1065 				/*
1066 				 * Should check for overflow, but it
1067 				 * "can't happen".
1068 				 */
1069 				if (opt == IPOPT_RR || opt == IPOPT_TS ||
1070 				    opt == IPOPT_SECURITY) {
1071 					bcopy(cp,
1072 					      mtod(opts, caddr_t) + opts->m_len,
1073 					      len);
1074 					opts->m_len += len;
1075 				}
1076 			}
1077 			/* Terminate & pad, if necessary */
1078 			cnt = opts->m_len % 4;
1079 			if (cnt) {
1080 				for (; cnt < 4; cnt++) {
1081 					*(mtod(opts, caddr_t) + opts->m_len) =
1082 					    IPOPT_EOL;
1083 					opts->m_len++;
1084 				}
1085 			}
1086 #ifdef ICMPPRINTFS
1087 			if (icmpprintfs)
1088 				kprintf("%d\n", opts->m_len);
1089 #endif
1090 		}
1091 		/*
1092 		 * Now strip out original options by copying rest of first
1093 		 * mbuf's data back, and adjust the IP length.
1094 		 */
1095 		ip->ip_len -= optlen;
1096 		ip->ip_vhl = IP_VHL_BORING;
1097 		m->m_len -= optlen;
1098 		if (m->m_flags & M_PKTHDR)
1099 			m->m_pkthdr.len -= optlen;
1100 		optlen += sizeof(struct ip);
1101 		bcopy((caddr_t)ip + optlen, ip + 1,
1102 		      m->m_len - sizeof(struct ip));
1103 	}
1104 	m->m_pkthdr.fw_flags &= FW_MBUF_GENERATED;
1105 	m->m_flags &= ~(M_BCAST|M_MCAST);
1106 	icmp_send(m, opts, ro);
1107 done:
1108 	if (opts)
1109 		m_free(opts);
1110 	if (ro && ro->ro_rt)
1111 		RTFREE(ro->ro_rt);
1112 }
1113 
1114 /*
1115  * Send an icmp packet back to the ip level,
1116  * after supplying a checksum.
1117  */
1118 static void
1119 icmp_send(struct mbuf *m, struct mbuf *opts, struct route *rt)
1120 {
1121 	struct ip *ip = mtod(m, struct ip *);
1122 	struct icmp *icp;
1123 	int hlen;
1124 
1125 	hlen = IP_VHL_HL(ip->ip_vhl) << 2;
1126 	m->m_data += hlen;
1127 	m->m_len -= hlen;
1128 	icp = mtod(m, struct icmp *);
1129 	icp->icmp_cksum = 0;
1130 	icp->icmp_cksum = in_cksum(m, ip->ip_len - hlen);
1131 	m->m_data -= hlen;
1132 	m->m_len += hlen;
1133 	m->m_pkthdr.rcvif = NULL;
1134 #ifdef ICMPPRINTFS
1135 	if (icmpprintfs) {
1136 		char dst_buf[INET_ADDRSTRLEN], src_buf[INET_ADDRSTRLEN];
1137 
1138 		kprintf("icmp_send dst %s src %s\n",
1139 		    inet_ntop(AF_INET, &ip->ip_dst, dst_buf, INET_ADDRSTRLEN),
1140 		    inet_ntop(AF_INET, &ip->ip_src, src_buf, INET_ADDRSTRLEN));
1141 	}
1142 #endif
1143 	ip_output(m, opts, rt, 0, NULL, NULL);
1144 }
1145 
1146 n_time
1147 iptime(void)
1148 {
1149 	struct timeval atv;
1150 	u_long t;
1151 
1152 	getmicrotime(&atv);
1153 	t = (atv.tv_sec % (24*60*60)) * 1000 + atv.tv_usec / 1000;
1154 	return (htonl(t));
1155 }
1156 
1157 #if 1
1158 /*
1159  * Return the next larger or smaller MTU plateau (table from RFC 1191)
1160  * given current value MTU.  If DIR is less than zero, a larger plateau
1161  * is returned; otherwise, a smaller value is returned.
1162  */
1163 int
1164 ip_next_mtu(int mtu, int dir)
1165 {
1166 	static int mtutab[] = {
1167 		65535, 32000, 17914, 8166, 4352, 2002, 1492, 1006, 508, 296,
1168 		68, 0
1169 	};
1170 	int i;
1171 
1172 	for (i = 0; i < (sizeof mtutab) / (sizeof mtutab[0]); i++) {
1173 		if (mtu >= mtutab[i])
1174 			break;
1175 	}
1176 
1177 	if (dir < 0) {
1178 		if (i == 0) {
1179 			return 0;
1180 		} else {
1181 			return mtutab[i - 1];
1182 		}
1183 	} else {
1184 		if (mtutab[i] == 0) {
1185 			return 0;
1186 		} else if(mtu > mtutab[i]) {
1187 			return mtutab[i];
1188 		} else {
1189 			return mtutab[i + 1];
1190 		}
1191 	}
1192 }
1193 #endif
1194 
1195 #ifdef ICMP_BANDLIM
1196 /*
1197  * badport_bandlim() - check for ICMP bandwidth limit
1198  *
1199  *	Return 0 if it is ok to send an ICMP error response, -1 if we have
1200  *	hit our bandwidth limit and it is not ok.
1201  *
1202  *	If icmplim is <= 0, the feature is disabled and 0 is returned.
1203  *
1204  *	For now we separate the TCP and UDP subsystems w/ different 'which'
1205  *	values.  We may eventually remove this separation (and simplify the
1206  *	code further).
1207  *
1208  *	Note that the printing of the error message is delayed so we can
1209  *	properly print the icmp error rate that the system was trying to do
1210  *	(i.e. 22000/100 pps, etc...).  This can cause long delays in printing
1211  *	the 'final' error, but it doesn't make sense to solve the printing
1212  *	delay with more complex code.
1213  */
1214 int
1215 badport_bandlim(int which)
1216 {
1217 	static int lticks[BANDLIM_MAX + 1];
1218 	static int lpackets[BANDLIM_MAX + 1];
1219 	int dticks;
1220 	const char *bandlimittype[] = {
1221 		"Limiting icmp unreach response",
1222 		"Limiting icmp ping response",
1223 		"Limiting icmp tstamp response",
1224 		"Limiting closed port RST response",
1225 		"Limiting open port RST response"
1226 		};
1227 
1228 	/*
1229 	 * Return ok status if feature disabled or argument out of
1230 	 * ranage.
1231 	 */
1232 
1233 	if (icmplim <= 0 || which > BANDLIM_MAX || which < 0)
1234 		return(0);
1235 	dticks = ticks - lticks[which];
1236 
1237 	/*
1238 	 * reset stats when cumulative dt exceeds one second.
1239 	 */
1240 
1241 	if ((unsigned int)dticks > hz) {
1242 		if (lpackets[which] > icmplim && icmplim_output) {
1243 			kprintf("%s from %d to %d packets per second\n",
1244 				bandlimittype[which],
1245 				lpackets[which],
1246 				icmplim
1247 			);
1248 		}
1249 		lticks[which] = ticks;
1250 		lpackets[which] = 0;
1251 	}
1252 
1253 	/*
1254 	 * bump packet count
1255 	 */
1256 
1257 	if (++lpackets[which] > icmplim) {
1258 		return(-1);
1259 	}
1260 	return(0);
1261 }
1262 #endif
1263