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 --- |