⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ip_icmp.c

📁 VXWORKS源代码
💻 C
📖 第 1 页 / 共 3 页
字号:
icmp_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;#ifndef VIRTUAL_STACK	extern u_char ip_protox[];#endif /* VIRTUAL_STACK */#ifdef WV_INSTRUMENTATION#ifdef INCLUDE_WVNET    /* WV_NET_NOTICE event */    WV_NET_EVENT_0 (NET_CORE_EVENT, WV_NET_NOTICE, 7, 8,                     WV_NETEVENT_ICMPIN_START, WV_NET_RECV)#endif  /* INCLUDE_WVNET */#endif	/*	 * 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) {#ifdef WV_INSTRUMENTATION#ifdef INCLUDE_WVNET    /* WV_NET_CRITICAL event */        WV_NET_ADDRIN_EVENT_0 (NET_CORE_EVENT, WV_NET_CRITICAL, 9, 3,                               ip->ip_src.s_addr, ip->ip_dst.s_addr,                               WV_NETEVENT_ICMPIN_SHORTMSG, WV_NET_RECV)#endif  /* INCLUDE_WVNET */#endif#ifdef VIRTUAL_STACK		_icmpstat.icps_tooshort++;#else		icmpstat.icps_tooshort++;#endif /* VIRTUAL_STACK */		goto freeit;	}	i = hlen + min(icmplen, ICMP_ADVLENMIN);	if (m->m_len < i && (m = m_pullup(m, i)) == 0)  {#ifdef WV_INSTRUMENTATION#ifdef INCLUDE_WVNET    /* WV_NET_CRITICAL event */        WV_NET_ADDRIN_EVENT_0 (NET_CORE_EVENT, WV_NET_CRITICAL, 9, 3,                               ip->ip_src.s_addr, ip->ip_dst.s_addr,                               WV_NETEVENT_ICMPIN_SHORTMSG, WV_NET_RECV)#endif  /* INCLUDE_WVNET */#endif#ifdef VIRTUAL_STACK		_icmpstat.icps_tooshort++;#else		icmpstat.icps_tooshort++;#endif /* VIRTUAL_STACK */		return;	}	ip = mtod(m, struct ip *);	m->m_len -= hlen;	m->m_data += hlen;	icp = mtod(m, struct icmp *);	if (in_cksum(m, icmplen)) {#ifdef WV_INSTRUMENTATION#ifdef INCLUDE_WVNET    /* WV_NET_CRITICAL event */        WV_NET_ADDRIN_EVENT_0 (NET_CORE_EVENT, WV_NET_CRITICAL, 10, 4,                               ip->ip_src.s_addr, ip->ip_dst.s_addr,                               WV_NETEVENT_ICMPIN_BADSUM, WV_NET_RECV)#endif  /* INCLUDE_WVNET */#endif#ifdef VIRTUAL_STACK		_icmpstat.icps_checksum++;#else		icmpstat.icps_checksum++;#endif /* VIRTUAL_STACK */		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;#ifdef VIRTUAL_STACK	_icmpstat.icps_inhist[icp->icmp_type]++;#else	icmpstat.icps_inhist[icp->icmp_type]++;#endif /* VIRTUAL_STACK */	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;		goto deliver;	case ICMP_SOURCEQUENCH:		if (code)			goto badcode;		code = PRC_QUENCH;	deliver:		/*		 * Problem with datagram; advise higher level routines.		 */		if (icmplen < ICMP_ADVLENMIN || icmplen < ICMP_ADVLEN(icp) ||		    icp->icmp_ip.ip_hl < (sizeof(struct ip) >> 2)) {#ifdef WV_INSTRUMENTATION#ifdef INCLUDE_WVNET    /* WV_NET_CRITICAL event */            WV_NET_ADDRIN_EVENT_2 (NET_CORE_EVENT, WV_NET_CRITICAL, 11, 5,                                    ip->ip_src.s_addr, ip->ip_dst.s_addr,                                   WV_NETEVENT_ICMPIN_BADLEN, WV_NET_RECV,                                   icmplen, 4 * icp->icmp_ip.ip_hl)#endif  /* INCLUDE_WVNET */#endif#ifdef VIRTUAL_STACK			_icmpstat.icps_badlen++;#else			icmpstat.icps_badlen++;#endif /* VIRTUAL_STACK */			goto freeit;		}		NTOHS(icp->icmp_ip.ip_len);#ifdef ICMPPRINTFS		if (icmpprintfs)			printf("deliver to protocol %d\n", icp->icmp_ip.ip_p);#endif		icmpsrc.sin_addr = icp->icmp_ip.ip_dst;                /* Path MTU discovery: get new MTU value. */                if (code == PRC_MSGSIZE)                    {                    i = ntohs (icp->icmp_nextmtu);                    ip_next_mtu ( (struct sockaddr *)&icmpsrc, i);                    }		if ((ctlfunc =                   (FUNCPTR)(inetsw[ip_protox[icp->icmp_ip.ip_p]].pr_ctlinput)))					(*ctlfunc)(code, (struct sockaddr *)&icmpsrc,			    &icp->icmp_ip);		break;	badcode:#ifdef VIRTUAL_STACK		_icmpstat.icps_badcode++;#else		icmpstat.icps_badcode++;#endif /* VIRTUAL_STACK */		break;	case ICMP_ECHO:		icp->icmp_type = ICMP_ECHOREPLY;		goto reflect;	case ICMP_TSTAMP:		if (icmplen < ICMP_TSLEN) {#ifdef VIRTUAL_STACK			_icmpstat.icps_badlen++;#else			icmpstat.icps_badlen++;#endif /* VIRTUAL_STACK */			break;		}		icp->icmp_type = ICMP_TSTAMPREPLY;		icp->icmp_rtime = iptime();		icp->icmp_ttime = icp->icmp_rtime;	/* bogus, do later! */		goto reflect;			case ICMP_MASKREQ:#define	satosin(sa)	((struct sockaddr_in *)(sa))		if (icmpmaskrepl == 0)			break;		/*		 * We are not able to respond with all ones broadcast		 * unless we receive it over a point-to-point interface.		 */		if (icmplen < ICMP_MASKLEN)			break;		switch (ip->ip_dst.s_addr) {		case INADDR_BROADCAST:		case INADDR_ANY:			icmpdst.sin_addr = ip->ip_src;			break;		default:			icmpdst.sin_addr = ip->ip_dst;		}		ia = (struct in_ifaddr *)ifaof_ifpforaddr(			    (struct sockaddr *)&icmpdst, m->m_pkthdr.rcvif);		if (ia == 0 || ia->ia_ifp == 0)			break;		icp->icmp_type = ICMP_MASKREPLY;		icp->icmp_mask = ia->ia_sockmask.sin_addr.s_addr;		if (ip->ip_src.s_addr == 0) {			if (ia->ia_ifp->if_flags & IFF_BROADCAST)			    ip->ip_src = satosin(&ia->ia_broadaddr)->sin_addr;			else if (ia->ia_ifp->if_flags & IFF_POINTOPOINT)			    ip->ip_src = satosin(&ia->ia_dstaddr)->sin_addr;		}reflect:		ip->ip_len += hlen;	/* since ip_input deducts this */#ifdef VIRTUAL_STACK		_icmpstat.icps_reflect++;		_icmpstat.icps_outhist[icp->icmp_type]++;#else		icmpstat.icps_reflect++;		icmpstat.icps_outhist[icp->icmp_type]++;#endif /* VIRTUAL_STACK */		icmp_reflect(m);		return; 	case ICMP_REDIRECT:		if (code > 3)			goto badcode;		if (icmplen < ICMP_ADVLENMIN || icmplen < ICMP_ADVLEN(icp) ||		    icp->icmp_ip.ip_hl < (sizeof(struct ip) >> 2)) {#ifdef VIRTUAL_STACK			_icmpstat.icps_badlen++;#else			icmpstat.icps_badlen++;#endif /* VIRTUAL_STACK */			break;		}		/*		 * Short circuit routing redirects to force		 * immediate change in the kernel's routing		 * tables.  The message is also handed to anyone		 * listening on a raw socket (e.g. the routing		 * daemon for use in updating its tables).		 */		icmpgw.sin_addr = ip->ip_src;		icmpdst.sin_addr = icp->icmp_gwaddr;#ifdef	ICMPPRINTFS		if (icmpprintfs)			printf("redirect dst %x to %x\n", icp->icmp_ip.ip_dst,				icp->icmp_gwaddr);#endif		icmpsrc.sin_addr = icp->icmp_ip.ip_dst;		rtredirect((struct sockaddr *)&icmpsrc,		  (struct sockaddr *)&icmpdst,		  (struct sockaddr *)0, RTF_GATEWAY | RTF_HOST,		  (struct sockaddr *)&icmpgw, (struct rtentry **)0);		pfctlinput(PRC_REDIRECT_HOST, (struct sockaddr *)&icmpsrc);		break;	/*	 * No kernel processing for the following;	 * just fall through to send to raw listener.	 */	case ICMP_ECHOREPLY:	case ICMP_ROUTERADVERT:	case ICMP_ROUTERSOLICIT:	case ICMP_TSTAMPREPLY:	case ICMP_IREQREPLY:	case ICMP_MASKREPLY:	default:		break;	}raw:	rip_input(m);	return;freeit:	m_freem(m);	return;}/* * Reflect the ip packet back to the source */static voidicmp_reflect(m)	struct mbuf *m;{	register struct ip *ip = mtod(m, struct ip *);	register struct in_ifaddr *ia;	struct in_addr t;	struct mbuf *opts = 0, *ip_srcroute();	int optlen = (ip->ip_hl << 2) - sizeof(struct ip);#ifdef WV_INSTRUMENTATION#ifdef INCLUDE_WVNET    /* WV_NET_NOTICE event */    WV_NET_EVENT_1 (NET_CORE_EVENT, WV_NET_NOTICE, 8, 9,                     WV_NETEVENT_ICMPREFLECT_START, WV_NET_SEND,                    ip->ip_src.s_addr)#endif  /* INCLUDE_WVNET */#endif	if (!in_canforward(ip->ip_src) &&	    ((ntohl(ip->ip_src.s_addr) & IN_CLASSA_NET) !=	     (IN_LOOPBACKNET << IN_CLASSA_NSHIFT))) {		m_freem(m);	/* Bad return address */		goto done;	/* Ip_output() will check for broadcast */	}	t = ip->ip_dst;	ip->ip_dst = ip->ip_src;	/*	 * If the incoming packet was addressed directly to us,	 * use dst as the src for the reply.  Otherwise (broadcast	 * or anonymous), use the address which corresponds	 * to the incoming interface.	 */#ifdef VIRTUAL_STACK	for (ia = _in_ifaddr; ia; ia = ia->ia_next) {#else	for (ia = in_ifaddr; ia; ia = ia->ia_next) {#endif /* VIRTUAL_STACK */		if (t.s_addr == IA_SIN(ia)->sin_addr.s_addr)			break;		if (ia->ia_ifp && (ia->ia_ifp->if_flags & IFF_BROADCAST) &&		    t.s_addr == satosin(&ia->ia_broadaddr)->sin_addr.s_addr)			break;	}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -