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