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