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
--- 17 unchanged lines hidden (view full) ---
26 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
27 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
30 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
31 * SUCH DAMAGE.
32 *
33 * @(#)ip_icmp.c 8.2 (Berkeley) 1/4/94
34 * $FreeBSD: head/sys/netinet/ip_icmp.c 55009 1999-12-22 19:13:38Z shin $
35 */
36
37#include "opt_ipsec.h"
38
39#include <sys/param.h>
40#include <sys/systm.h>
41#include <sys/mbuf.h>
42#include <sys/protosw.h>
43#include <sys/socket.h>
44#include <sys/time.h>
45#include <sys/kernel.h>
46#include <sys/sysctl.h>
--- 5 unchanged lines hidden (view full) ---
52#include <netinet/in.h>
53#include <netinet/in_systm.h>
54#include <netinet/in_var.h>
55#include <netinet/ip.h>
56#include <netinet/ip_icmp.h>
57#include <netinet/ip_var.h>
58#include <netinet/icmp_var.h>
59
60#ifdef IPSEC
61#include <netinet6/ipsec.h>
62#include <netkey/key.h>
63#endif
64
65#include "faith.h"
66#if defined(NFAITH) && NFAITH > 0
67#include <net/if_types.h>
68#endif
69
70/*
71 * ICMP routines: error generation, receive packet processing, and
72 * routines to turnaround packets back to the originator, and
73 * host table maintenance routines.
74 */
75
76static struct icmpstat icmpstat;
77SYSCTL_STRUCT(_net_inet_icmp, ICMPCTL_STATS, stats, CTLFLAG_RD,
--- 148 unchanged lines hidden (view full) ---
226static struct sockaddr_in icmpsrc = { sizeof (struct sockaddr_in), AF_INET };
227static struct sockaddr_in icmpdst = { sizeof (struct sockaddr_in), AF_INET };
228static struct sockaddr_in icmpgw = { sizeof (struct sockaddr_in), AF_INET };
229
230/*
231 * Process a received ICMP message.
232 */
233void
234icmp_input(m, off, proto)
235 register struct mbuf *m;
236 int off, proto;
237{
238 int hlen = off;
239 register struct icmp *icp;
240 register struct ip *ip = mtod(m, struct ip *);
241 int icmplen = ip->ip_len;
242 register int i;
243 struct in_ifaddr *ia;
244 void (*ctlfunc) __P((int, struct sockaddr *, void *));
245 int code;
246
--- 24 unchanged lines hidden (view full) ---
271 icp = mtod(m, struct icmp *);
272 if (in_cksum(m, icmplen)) {
273 icmpstat.icps_checksum++;
274 goto freeit;
275 }
276 m->m_len += hlen;
277 m->m_data -= hlen;
278
279#if defined(NFAITH) && 0 < NFAITH
280 if (m->m_pkthdr.rcvif && m->m_pkthdr.rcvif->if_type == IFT_FAITH) {
281 /*
282 * Deliver very specific ICMP type only.
283 */
284 switch (icp->icmp_type) {
285 case ICMP_UNREACH:
286 case ICMP_TIMXCEED:
287 break;
288 default:
289 goto freeit;
290 }
291 }
292#endif
293
294#ifdef ICMPPRINTFS
295 if (icmpprintfs)
296 printf("icmp_input, type %d code %d\n", icp->icmp_type,
297 icp->icmp_code);
298#endif
299
300#ifdef IPSEC
301 /* drop it if it does not match the policy */
302 /* XXX Is there meaning of check in here ? */
303 if (ipsec4_in_reject(m, NULL)) {
304 ipsecstat.in_polvio++;
305 goto freeit;
306 }
307#endif
308
309 /*
310 * Message type specific processing.
311 */
312 if (icp->icmp_type > ICMP_MAXTYPE)
313 goto raw;
314 icmpstat.icps_inhist[icp->icmp_type]++;
315 code = icp->icmp_code;
316 switch (icp->icmp_type) {
--- 109 unchanged lines hidden (view full) ---
426 rt->rt_rmx.rmx_mtu = mtu;
427 }
428 }
429 if (rt)
430 RTFREE(rt);
431 }
432
433#endif
434 /*
435 * XXX if the packet contains [IPv4 AH TCP], we can't make a
436 * notification to TCP layer.
437 */
438 ctlfunc = inetsw[ip_protox[icp->icmp_ip.ip_p]].pr_ctlinput;
439 if (ctlfunc)
440 (*ctlfunc)(code, (struct sockaddr *)&icmpsrc,
441 (void *)&icp->icmp_ip);
442 break;
443
444 badcode:
445 icmpstat.icps_badcode++;
--- 108 unchanged lines hidden (view full) ---
554 }
555#endif
556 icmpsrc.sin_addr = icp->icmp_ip.ip_dst;
557 rtredirect((struct sockaddr *)&icmpsrc,
558 (struct sockaddr *)&icmpdst,
559 (struct sockaddr *)0, RTF_GATEWAY | RTF_HOST,
560 (struct sockaddr *)&icmpgw, (struct rtentry **)0);
561 pfctlinput(PRC_REDIRECT_HOST, (struct sockaddr *)&icmpsrc);
562#ifdef IPSEC
563 key_sa_routechange((struct sockaddr *)&icmpsrc);
564#endif
565 break;
566
567 /*
568 * No kernel processing for the following;
569 * just fall through to send to raw listener.
570 */
571 case ICMP_ECHOREPLY:
572 case ICMP_ROUTERADVERT:
573 case ICMP_ROUTERSOLICIT:
574 case ICMP_TSTAMPREPLY:
575 case ICMP_IREQREPLY:
576 case ICMP_MASKREPLY:
577 default:
578 break;
579 }
580
581raw:
582 rip_input(m, off, proto);
583 return;
584
585freeit:
586 m_freem(m);
587}
588
589/*
590 * Reflect the ip packet back to the source
--- 275 unchanged lines hidden ---
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
--- 17 unchanged lines hidden (view full) ---
26 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
27 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
30 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
31 * SUCH DAMAGE.
32 *
33 * @(#)ip_icmp.c 8.2 (Berkeley) 1/4/94
34 * $FreeBSD: head/sys/netinet/ip_icmp.c 55009 1999-12-22 19:13:38Z shin $
35 */
36
37#include "opt_ipsec.h"
38
39#include <sys/param.h>
40#include <sys/systm.h>
41#include <sys/mbuf.h>
42#include <sys/protosw.h>
43#include <sys/socket.h>
44#include <sys/time.h>
45#include <sys/kernel.h>
46#include <sys/sysctl.h>
--- 5 unchanged lines hidden (view full) ---
52#include <netinet/in.h>
53#include <netinet/in_systm.h>
54#include <netinet/in_var.h>
55#include <netinet/ip.h>
56#include <netinet/ip_icmp.h>
57#include <netinet/ip_var.h>
58#include <netinet/icmp_var.h>
59
60#ifdef IPSEC
61#include <netinet6/ipsec.h>
62#include <netkey/key.h>
63#endif
64
65#include "faith.h"
66#if defined(NFAITH) && NFAITH > 0
67#include <net/if_types.h>
68#endif
69
70/*
71 * ICMP routines: error generation, receive packet processing, and
72 * routines to turnaround packets back to the originator, and
73 * host table maintenance routines.
74 */
75
76static struct icmpstat icmpstat;
77SYSCTL_STRUCT(_net_inet_icmp, ICMPCTL_STATS, stats, CTLFLAG_RD,
--- 148 unchanged lines hidden (view full) ---
226static struct sockaddr_in icmpsrc = { sizeof (struct sockaddr_in), AF_INET };
227static struct sockaddr_in icmpdst = { sizeof (struct sockaddr_in), AF_INET };
228static struct sockaddr_in icmpgw = { sizeof (struct sockaddr_in), AF_INET };
229
230/*
231 * Process a received ICMP message.
232 */
233void
234icmp_input(m, off, proto)
235 register struct mbuf *m;
236 int off, proto;
237{
238 int hlen = off;
239 register struct icmp *icp;
240 register struct ip *ip = mtod(m, struct ip *);
241 int icmplen = ip->ip_len;
242 register int i;
243 struct in_ifaddr *ia;
244 void (*ctlfunc) __P((int, struct sockaddr *, void *));
245 int code;
246
--- 24 unchanged lines hidden (view full) ---
271 icp = mtod(m, struct icmp *);
272 if (in_cksum(m, icmplen)) {
273 icmpstat.icps_checksum++;
274 goto freeit;
275 }
276 m->m_len += hlen;
277 m->m_data -= hlen;
278
279#if defined(NFAITH) && 0 < NFAITH
280 if (m->m_pkthdr.rcvif && m->m_pkthdr.rcvif->if_type == IFT_FAITH) {
281 /*
282 * Deliver very specific ICMP type only.
283 */
284 switch (icp->icmp_type) {
285 case ICMP_UNREACH:
286 case ICMP_TIMXCEED:
287 break;
288 default:
289 goto freeit;
290 }
291 }
292#endif
293
294#ifdef ICMPPRINTFS
295 if (icmpprintfs)
296 printf("icmp_input, type %d code %d\n", icp->icmp_type,
297 icp->icmp_code);
298#endif
299
300#ifdef IPSEC
301 /* drop it if it does not match the policy */
302 /* XXX Is there meaning of check in here ? */
303 if (ipsec4_in_reject(m, NULL)) {
304 ipsecstat.in_polvio++;
305 goto freeit;
306 }
307#endif
308
309 /*
310 * Message type specific processing.
311 */
312 if (icp->icmp_type > ICMP_MAXTYPE)
313 goto raw;
314 icmpstat.icps_inhist[icp->icmp_type]++;
315 code = icp->icmp_code;
316 switch (icp->icmp_type) {
--- 109 unchanged lines hidden (view full) ---
426 rt->rt_rmx.rmx_mtu = mtu;
427 }
428 }
429 if (rt)
430 RTFREE(rt);
431 }
432
433#endif
434 /*
435 * XXX if the packet contains [IPv4 AH TCP], we can't make a
436 * notification to TCP layer.
437 */
438 ctlfunc = inetsw[ip_protox[icp->icmp_ip.ip_p]].pr_ctlinput;
439 if (ctlfunc)
440 (*ctlfunc)(code, (struct sockaddr *)&icmpsrc,
441 (void *)&icp->icmp_ip);
442 break;
443
444 badcode:
445 icmpstat.icps_badcode++;
--- 108 unchanged lines hidden (view full) ---
554 }
555#endif
556 icmpsrc.sin_addr = icp->icmp_ip.ip_dst;
557 rtredirect((struct sockaddr *)&icmpsrc,
558 (struct sockaddr *)&icmpdst,
559 (struct sockaddr *)0, RTF_GATEWAY | RTF_HOST,
560 (struct sockaddr *)&icmpgw, (struct rtentry **)0);
561 pfctlinput(PRC_REDIRECT_HOST, (struct sockaddr *)&icmpsrc);
562#ifdef IPSEC
563 key_sa_routechange((struct sockaddr *)&icmpsrc);
564#endif
565 break;
566
567 /*
568 * No kernel processing for the following;
569 * just fall through to send to raw listener.
570 */
571 case ICMP_ECHOREPLY:
572 case ICMP_ROUTERADVERT:
573 case ICMP_ROUTERSOLICIT:
574 case ICMP_TSTAMPREPLY:
575 case ICMP_IREQREPLY:
576 case ICMP_MASKREPLY:
577 default:
578 break;
579 }
580
581raw:
582 rip_input(m, off, proto);
583 return;
584
585freeit:
586 m_freem(m);
587}
588
589/*
590 * Reflect the ip packet back to the source
--- 275 unchanged lines hidden ---