📄 ip_icmp.c
字号:
/* ip_icmp.c - internet ICMP routines *//* Copyright 1984 - 1999 Wind River Systems, Inc. */#include "copyright_wrs.h"/* * Copyright (c) 1982, 1986, 1988, 1993 * The Regents of the University of California. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. All advertising materials mentioning features or use of this software * must display the following acknowledgement: * This product includes software developed by the University of * California, Berkeley and its contributors. * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * * @(#)ip_icmp.c 8.2 (Berkeley) 1/4/94 *//*modification history--------------------03e,16mar99,spm recovered orphaned code from tor2_0_x branch (SPR #25770)03d,09feb99,ham fixed SPR#24975.03c,31jan97,vin changed declaration according to prototype decl in protosw.h03b,07jan96,vin added icmp_init(..) for scalability, moved iptime to ip_input.c03a,31oct96,vin changed m_gethdr(..) to mHdrClGet(..).02u,24aug96,vin integrated with BSD44 and 02t of ip_icmp.c.*//* * ICMP routines: error generation, receive packet processing, and * routines to turnaround packets back to the originator, and * host table maintenance routines. */#include "vxWorks.h"#include "net/mbuf.h"#include "net/protosw.h"#include "sys/socket.h"#include "net/systm.h"#include "net/route.h"#include "net/if.h"#include "netinet/in.h"#include "netinet/in_systm.h"#include "netinet/in_var.h"#include "netinet/ip.h"#include "netinet/ip_var.h"#include "netinet/ip_icmp.h"#include "netinet/icmp_var.h"/* externs */extern pfctlinput ();extern struct protosw inetsw[];extern VOIDFUNCPTR _icmpErrorHook; /* globals */struct icmpstat icmpstat;struct sockaddr_in icmpmask = { 8, 0 };int icmpmaskrepl = 0;#ifdef ICMPPRINTFSint icmpprintfs = 0;#endif/* locals */static struct sockaddr_in icmpsrc = { sizeof (struct sockaddr_in), AF_INET };static struct sockaddr_in icmpdst = { sizeof (struct sockaddr_in), AF_INET };static struct sockaddr_in icmpgw = { sizeof (struct sockaddr_in), AF_INET };/* forward declarations */static void icmp_error (struct mbuf *, int, int, n_long, struct ifnet *);static void icmp_reflect (struct mbuf *);static void icmp_send (struct mbuf *, struct mbuf *);voidicmp_init(){ if (_icmpErrorHook == NULL) /* initialize the hook if not null */ _icmpErrorHook = icmp_error; }/* * ICMP routines: error generation, receive packet processing, and * routines to turnaround packets back to the originator, and * host table maintenance routines. *//* * Generate an error packet of type error * in response to bad packet ip. */static voidicmp_error(n, type, code, dest, destifp) struct mbuf *n; int type, code; n_long dest; struct ifnet *destifp;{ register struct ip *oip = mtod(n, struct ip *), *nip; register unsigned oiplen = oip->ip_hl << 2; register struct icmp *icp; register struct mbuf *m; unsigned icmplen;#ifdef ICMPPRINTFS if (icmpprintfs) printf("icmp_error(%x, %d, %d)\n", oip, type, code);#endif if (type != ICMP_REDIRECT) icmpstat.icps_error++; /* * Don't send error if not the first fragment of message. * Don't error if the old packet protocol was ICMP * error message, only known informational types. */ if (oip->ip_off &~ (IP_MF|IP_DF)) goto freeit; if (oip->ip_p == IPPROTO_ICMP && type != ICMP_REDIRECT && n->m_len >= oiplen + ICMP_MINLEN && !ICMP_INFOTYPE(((struct icmp *)((caddr_t)oip + oiplen))->icmp_type)) { icmpstat.icps_oldicmp++; goto freeit; } /* Don't send error in response to a multicast or broadcast packet */ if (n->m_flags & (M_BCAST|M_MCAST)) goto freeit; /* * First, formulate icmp message */ if ((m = mHdrClGet(M_DONTWAIT, MT_HEADER, CL_SIZE_128, TRUE)) == NULL) goto freeit; icmplen = oiplen + min(8, oip->ip_len); m->m_len = icmplen + ICMP_MINLEN; MH_ALIGN(m, m->m_len); icp = mtod(m, struct icmp *); if ((u_int)type > ICMP_MAXTYPE) panic("icmp_error"); icmpstat.icps_outhist[type]++; icp->icmp_type = type; if (type == ICMP_REDIRECT) icp->icmp_gwaddr.s_addr = dest; else { icp->icmp_void = 0; /* * The following assignments assume an overlay with the * zeroed icmp_void field. */ if (type == ICMP_PARAMPROB) { icp->icmp_pptr = code; code = 0; } else if (type == ICMP_UNREACH && code == ICMP_UNREACH_NEEDFRAG && destifp) { icp->icmp_nextmtu = htons(destifp->if_mtu); } } icp->icmp_code = code; bcopy((caddr_t)oip, (caddr_t)&icp->icmp_ip, icmplen); nip = &icp->icmp_ip; nip->ip_len = htons((u_short)(nip->ip_len + oiplen)); /* * Now, copy old ip header (without options) * in front of icmp message. */ if (m->m_data - sizeof(struct ip) < m->m_extBuf) panic("icmp len"); m->m_data -= sizeof(struct ip); m->m_len += sizeof(struct ip); m->m_pkthdr.len = m->m_len; m->m_pkthdr.rcvif = n->m_pkthdr.rcvif; nip = mtod(m, struct ip *); bcopy((caddr_t)oip, (caddr_t)nip, sizeof(struct ip)); nip->ip_len = m->m_len; nip->ip_hl = sizeof(struct ip) >> 2; nip->ip_p = IPPROTO_ICMP; nip->ip_tos = 0; icmp_reflect(m);freeit: m_freem(n);}/* * Process a received ICMP message. */voidicmp_input(m, hlen) register struct mbuf *m; int hlen;{ register struct icmp *icp; register struct ip *ip = mtod(m, struct ip *); int icmplen = ip->ip_len; register int i; struct in_ifaddr *ia; int (*ctlfunc) (int, struct sockaddr *, struct ip *); int code; extern u_char ip_protox[]; /* * Locate icmp structure in mbuf, and check * that not corrupted and of at least minimum length. */#ifdef ICMPPRINTFS if (icmpprintfs) printf("icmp_input from %x to %x, len %d\n", ntohl(ip->ip_src.s_addr), ntohl(ip->ip_dst.s_addr), icmplen);#endif if (icmplen < ICMP_MINLEN) { icmpstat.icps_tooshort++; goto freeit; } i = hlen + min(icmplen, ICMP_ADVLENMIN); if (m->m_len < i && (m = m_pullup(m, i)) == 0) { icmpstat.icps_tooshort++; return; } ip = mtod(m, struct ip *); m->m_len -= hlen; m->m_data += hlen; icp = mtod(m, struct icmp *); if (in_cksum(m, icmplen)) { icmpstat.icps_checksum++; goto freeit; } m->m_len += hlen; m->m_data -= hlen;#ifdef ICMPPRINTFS /* * Message type specific processing. */ if (icmpprintfs) printf("icmp_input, type %d code %d\n", icp->icmp_type, icp->icmp_code);#endif if (icp->icmp_type > ICMP_MAXTYPE) goto raw; icmpstat.icps_inhist[icp->icmp_type]++; code = icp->icmp_code; switch (icp->icmp_type) { case ICMP_UNREACH: switch (code) { case ICMP_UNREACH_NET: case ICMP_UNREACH_HOST: case ICMP_UNREACH_PROTOCOL: case ICMP_UNREACH_PORT: case ICMP_UNREACH_SRCFAIL: code += PRC_UNREACH_NET; break; case ICMP_UNREACH_NEEDFRAG: code = PRC_MSGSIZE; break; case ICMP_UNREACH_NET_UNKNOWN: case ICMP_UNREACH_NET_PROHIB: case ICMP_UNREACH_TOSNET: code = PRC_UNREACH_NET; break; case ICMP_UNREACH_HOST_UNKNOWN: case ICMP_UNREACH_ISOLATED: case ICMP_UNREACH_HOST_PROHIB: case ICMP_UNREACH_TOSHOST: code = PRC_UNREACH_HOST; break; default: goto badcode; } goto deliver; case ICMP_TIMXCEED: if (code > 1) goto badcode; code += PRC_TIMXCEED_INTRANS; goto deliver; case ICMP_PARAMPROB: if (code > 1) goto badcode; code = PRC_PARAMPROB;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -