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