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