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

📄 ip.c

📁 实现在ARM上的ICP/IP功能的源代码。
💻 C
字号:
#include "debug.h"
#include "true_false.h"
#include "stdlib.h"
#include "typedef.h"
#include "mem_man.h"
#include "rtl8019.h"
#include "netif.h"
#include "etherif.h"
#include "ip.h"
#include "arp.h"
#include "utilities.h"

u16_t fff(u16_t *dataptr,u16_t len,u32_t acc);
/* Check sum calulation. data in buff, size, InSum is initial sum */
WORD CheckSum(WORD   * buff,WORD size,DWORD InSum)  
{
	return ncs(buff,size,InSum);
}

/* IP input process */
void IPInput(struct SMemHead   *MemHead)  
{
	struct SIPHead   *pIPHead;
	struct SNetIf    *pNetIf;		/* for search netif list */

	pIPHead = (struct SIPHead   *)(MemHead->pStart);
#ifdef debug_ip
   	Uart_Printf( "\nIP RCV A FRAME...\n" ) ;
#endif
	/* check ip version */
	if(IP_VERSION(pIPHead) != IP_VERSION_4)
	{
		MemFree(MemHead);
		return;
	}

	/* if checksum is ok */
	if(CheckSum((WORD   *)pIPHead,(WORD)IP_HEAD_LEN(pIPHead),0) != 0)
	{
#ifdef debug_ip
	Uart_Printf("\nIP: there is an ERROR FRAME...E0\n");
#endif 		
		MemFree(MemHead);
		return;
	}

	/* ip packet with options is not supported */
	if(IP_HEAD_LEN(pIPHead) != IP_HEAD_MIN_LEN)
	{
	#ifdef debug_ip
	Uart_Printf("\nM12CS: there is an ERROR FRAME...E1\n");
	#endif	
		MemFree(MemHead);
		return;
	}

	/* ip packet fragmented is not supported */
/*	if((pIPHead->FragmentFlag_Offset & IP_FRAGMENT_OFFSET_MASK)!= 0)
	{
		Uart_Printf("\nM12CS: there is an ERROR FRAME...E2\n");
		MemFree(MemHead);
		return;
	}
*/
	
	/* if this packet for us. check all the netif. if a host
	has tow device(tow ip). This packet may come from one device
	but send for the IP of the other deviec. In this case we should
	not drop or forward this packet */
	
	/* if this packet is not for us. forward it */
	if((pNetIf = NetIfFindIP(pIPHead->IPDest)) == NULL)
	{
		#ifdef IP_ENABLE_FORWARD	/* if act as a router */
		/* We should decrease the IPHead->ttl */
		if(pIPHead->LifeLength != 0)
		{
			pIPHead->LifeLength--;
				
			/* recaculate IP head checksum. there is a easy method
			to recaculate, leave for later version improvment */
		//	CheckSum((WORD   *)pIPHead,(WORD)IP_HEAD_LEN(pIPHead),0);

			/* find a rout( a interface ) */
			if((pNetIf = NetIfFindRout(pIPHead->IPDest)) != NULL)
			{
				/* forward. send it through this interface. if return FALSE, we
				do not care, the soure of the packet will deel with it. */
				pNetIf->output(MemHead,pNetIf,pIPHead->IPDest);
			}
		}
		#endif
		
		MemFree(MemHead);
		return;
	}
	else
	{
		/* MemHead->pStart set to point uper layer */
		MemHead->pStart += sizeof(struct SIPHead);

		/* pass to the uper layer */
		switch(pIPHead->Protocol)
		{
		case IP_PROTOCOL_TCP:
		#ifdef debug_ip
		Uart_Printf("\nRCV A TCP FRAME...\n");
		#endif 
			TCPInput(MemHead);
			break;
			
		case IP_PROTOCOL_ICMP:
			ICMPInput(MemHead);
			break;
#ifdef debug_ip
Uart_Printf("\nM12CS: there is an ERROR FRAME...MEMFREE\n");
#endif 
		default:
			MemFree(MemHead);
		}
	}
}

/* out put a ip packet,NOTE:MemHead->pStart point to IPHead.
IPScr IPDest Protocol TotalLen is already filled at uper layer.
To do so TCPCheckSum is easy to generate and pass augument to 
IPOutput is easyer. 
return :
	TURE: send the packt successful. */
BOOL IPOutput(struct SMemHead   * MemHead)  
{
	struct SNetIf    *pNetIf;
	struct SIPHead   *pIPHead;
	WORD tCheckSum;
	
	pIPHead = (struct SIPHead   *)(MemHead->pStart);

	/* found a rout */
	if((pNetIf = NetIfFindRout(pIPHead->IPDest)) != NULL)
	{
		/* fill IP head */
		pIPHead->CheckSum				= 0;
		pIPHead->FragmentFlag_Offset	= 0;
		pIPHead->FragmentID				= 0;
		pIPHead->LifeLength				= IP_INITIAL_LIFE;
		pIPHead->ServeType				= 0;
		pIPHead->Ver_HeadLen			= (IP_VERSION_4 << 4) + IP_HEAD_MIN_LEN/4;

		/* checksum */
		tCheckSum = CheckSum((WORD *)pIPHead,(WORD)IP_HEAD_LEN(pIPHead),0);
		//pIPHead->CheckSum = htons(tCheckSum);
		pIPHead->CheckSum = (tCheckSum);
		/* output it */
		return pNetIf->output(MemHead,pNetIf,pIPHead->IPDest);
	}
	else
		return FALSE;
	/* 'MemHead' freeing is at tcp model when it is acked */
}

⌨️ 快捷键说明

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