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

📄 neticmp.c

📁 基于东南大学开发的SEP3203的ARM7中的所有驱动
💻 C
📖 第 1 页 / 共 2 页
字号:

		goto freeit;

	}



	/*

	 * Message type specific processing.

	 */

	ICMPDEBUG((LOG_INFO, "icmp_input, type %d code %d\n", icp->icmp_type,

		    icp->icmp_code));

	if (icp->icmp_type > ICMP_MAXTYPE)

		goto raw;

	icmpStats.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;

		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(IPHdr) >> 2)) {

			icmpStats.icps_badlen++;

			goto freeit;

		}

		NTOHS(icp->icmp_ip.ip_len);

		ICMPDEBUG((LOG_INFO, "icmp_input: deliver to protocol %d\n", icp->icmp_ip.ip_p));

		icmpsrc.sin_addr = icp->icmp_ip.ip_dst;

#ifdef XXX  /* We need a method here of selecting input handlers... */

		if (ctlfunc = inetsw[ip_protox[icp->icmp_ip.ip_p]].pr_ctlinput)

			(*ctlfunc)(code, (struct sockaddr *)&icmpsrc, &icp->icmp_ip);

#endif

		break;

	badcode:

		icmpStats.icps_badcode++;

		break;



	case ICMP_ECHO:

		icp->icmp_type = ICMP_ECHOREPLY;

		goto reflect;



	case ICMP_TSTAMP:

		if (icmplen < ICMP_TSLEN) {

			icmpStats.icps_badlen++;

			break;

		}

		icp->icmp_type = ICMP_TSTAMPREPLY;

		icp->icmp_rtime = iptime();

		icp->icmp_ttime = icp->icmp_rtime;	/* bogus, do later! */

		goto reflect;

		

	case ICMP_MASKREQ:

#ifdef XXX /* Not currently supported... */

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

			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;

		}

#else

		break;

#endif

reflect:

#ifdef XXX

	/* XXX No longer! */

		ip->ip_len += ipHdrLen;	/* since ip_input deducts this */

#endif

		icmpStats.icps_reflect++;

		icmpStats.icps_outhist[icp->icmp_type]++;

		icmpReflect(inBuf);

		return;



	case ICMP_REDIRECT:

#ifdef XXX /* Not currently supported... */

		if (code > 3)

			goto badcode;

		if (icmplen < ICMP_ADVLENMIN || icmplen < ICMP_ADVLEN(icp) ||

		    icp->icmp_ip.ip_hl < (sizeof(IPHdr) >> 2)) {

			icmpStats.icps_badlen++;

			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)

			ICMPDEBUG("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);

#endif

		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:

	ripInput(inBuf);

	return;



freeit:

	nFreeChain(inBuf);

}





/**********************************/

/*** LOCAL FUNCTION DEFINITIONS ***/

/**********************************/

/*

 * Reflect the ip packet back to the source

 */

static void icmpReflect(NBuf* nb)

{

	register IPHdr* ip = nBUFTOPTR(nb, IPHdr*);



	/* Send back to source, use our address as new source. */

	ip->ip_dst = ip->ip_src;

	ip->ip_src.s_addr = htonl(localHost);

	ip->ip_ttl = MAXTTL;

	icmpSend(nb, NULL);

}



/*

 * Send an icmp packet back to the ip level,

 * after supplying a checksum.

 */

static void icmpSend(register NBuf* nb,	NBuf* opts)

{

	register IPHdr* ip = nBUFTOPTR(nb, IPHdr*);

	register int ipHdrLen;

	register IcmpHdr* icp;



	/* Compute the ICMP checksum on the datagram body only. */

	ipHdrLen = ip->ip_hl << 2;

	icp = (IcmpHdr*)(nBUFTOPTR(nb, char*) + ipHdrLen);

	icp->icmp_cksum = 0;

	icp->icmp_cksum = inChkSum(nb, ip->ip_len - ipHdrLen, ipHdrLen);

	ICMPDEBUG((LOG_INFO, "icmp_send %d p%d t%d c%d from %s to %s chk=%X\n", 

				nb->len, ip->ip_p,

				icp->icmp_type, icp->icmp_code,

				ip_ntoa(ip->ip_src.s_addr), 

				ip_ntoa2(ip->ip_dst.s_addr),

				icp->icmp_cksum));

	ipRawOut(nb);

}



static u_long iptime(void)

{

	u_long t;

#if 1

	struct tm ctime;

	if (clk_stat()) {

		gettime(&ctime);

		t = ((((u_long)ctime.tm_hour * 24

			 + (u_long)ctime.tm_min) * 60

             + (u_long)ctime.tm_sec) * 60

#ifdef XXX	/* iptime includes thousands if possible */

						+ (u_long)ctime.hund

#endif

		    ) * 10;

	} else {

		t = 0;

    }

#else

    t = time(NULL);

#endif

	return (htonl(t));

}





#pragma warning (pop)

////////////////////////////////////////////////////////////////////////////////

⌨️ 快捷键说明

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