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

📄 arp.c

📁 opentcp_mcf5282原代码
💻 C
📖 第 1 页 / 共 2 页
字号:
			DEBUGOUT(" Refreshing Existing ARP Entry..\n\r");

			for( j=0; j<MAXHWALEN; j++ )
				qstruct->hwadr[j] = *hwadr++;

			qstruct->ttl = ARP_TIMEOUT;
			qstruct->retries = ARP_MAXRETRY;
			qstruct->state = ARP_RESOLVED;

			/* All OK	*/

			return (0);
		}

	}

	/* Does this address belong to outer world?				*/

	if( IsSub(pra, &localmachine) == 0)
		return(-1);

	if( localmachine.defgw == pra )
	{
		if(localmachine.defgw != 0)
		{
			type = ARP_FIXED_IP;
		}

	}

	/* Address was'nt on cache. Need to allocate new one	*/

	DEBUGOUT("Allocating New ARP Entry..\n\r");

	i = arpalloc(type);

	if( i < 0 )				/* No Entries Left?	*/
		return(-1);

	/* Fill the fields		*/

	qstruct = &arptable[i];

	qstruct->pradr = pra;										/* Fill IP				*/

	for(i=0; i<MAXHWALEN; i++)
		qstruct->hwadr[i] = *hwadr++;							/* Fill HW address		*/

	qstruct->retries = ARP_MAXRETRY;
	qstruct->ttl = ARP_TIMEOUT;
	qstruct->state = ARP_RESOLVED;

	DEBUGOUT("ARP Entry Created!..\n\r");

	return(1);

}

/******************************************************************************
Function:		arpfind

Parameters:		UINT32 pra - protocol address
				struct netif *localmachine - pointer to config. of network
										     interface used
				UINT8 type - type of address allocated if not found

Return val:		struct arpentry* - pointer to solved entry of arp table
				0 - entry not found or not ready yet

Date:			01.11.2001

Desc:			Find an ARP entry given a protocol address. If no entry is found,
				new one is allocated and ARPREQ sent.
*******************************************************************************/

struct arpentry* arpfind (LWORD pra, struct netif *machine, UINT8 type)
{
	struct arpentry *qstruct;
	INT8 i;

	DEBUGOUT("Trying to find MAC address from ARP Cache\n\r");


	/* Is the address in the cache	*/

	for( i=0; i<ARP_TSIZE; i++ )
	{
		qstruct = &arptable[i];

		if( qstruct->state == ARP_FREE )
			continue;
		if( qstruct->pradr == pra)
		{
			/* The address is in cache, is it valid? */

			DEBUGOUT("Address In Cache\n\r");

			if( qstruct->state < ARP_RESOLVED )
			{
				DEBUGOUT("Address in cache but unresolved :(\n\r");
				return(0);
			}
			/* All OK	*/

			return(qstruct);
		}

	}

	/* The address wasn't on the cache. Is it in our Subnet?	*/

	if( IsSub(pra, machine) )
	{
		/* Yep, we need to send ARP REQUEST	*/

		DEBUGOUT("Need to send ARP Request to local network..\n\r");

		if( machine->defgw == pra )
		{
			if(machine->defgw != 0)
			{
				type = ARP_FIXED_IP;
			}

		}

		i = arpalloc(type);

		if( i < 0 )				/* No Entries Left?	*/
			return(0);

		/* Send Request after filling the fields	*/

		qstruct = &arptable[i];

		qstruct->pradr = pra;						/* Fill IP				*/
		qstruct->hwadr[0] = 0xFF;					/* Fill Broadcast IP	*/
		qstruct->hwadr[1] = 0xFF;
		qstruct->hwadr[2] = 0xFF;
		qstruct->hwadr[3] = 0xFF;
		qstruct->hwadr[4] = 0xFF;
		qstruct->hwadr[5] = 0xFF;
		qstruct->retries = ARP_MAXRETRY;
		qstruct->ttl = ARP_RESEND;
		arpsendreq( i );
		qstruct->state = ARP_PENDING;				/* Waiting for Reply	*/

		return(0);

	}



	/* The Address belongst to the outern world, need to use MAC of			*/
	/* Default Gateway														*/

	DEBUGOUT("Need to use MAC of Default GW\n\r");

	if(machine->defgw == 0)				/* It's not specified	*/
		return(0);

	for( i=0; i<ARP_TSIZE; i++ )
	{
		qstruct = &arptable[i];

		if( qstruct->state == ARP_FREE )
			continue;

		if( qstruct->pradr == machine->defgw )
		{
			/* The address is in cache, is it valid? */


			if( qstruct->state < ARP_RESOLVED )
			{
				DEBUGOUT("The Address of Def. GW is not Solved!\n\r");
				return(0);
			}

			/* All OK	*/

			DEBUGOUT(" >> Default Gateway MAC found!\n\r");

			return(qstruct);

		}

	}

	/* No default GW address on cache, allocate entry for it?	*/

	i = arpalloc(ARP_FIXED_IP);

	if( i < 0 )				/* No Entries Left?	*/
		return(0);

	/* Send Request after filling the fields	*/

	qstruct = &arptable[i];

	qstruct->pradr = machine->defgw;			/* Fill IP				*/
	qstruct->hwadr[0] = 0xFF;					/* Fill Broadcast IP	*/
	qstruct->hwadr[1] = 0xFF;
	qstruct->hwadr[2] = 0xFF;
	qstruct->hwadr[3] = 0xFF;
	qstruct->hwadr[4] = 0xFF;
	qstruct->hwadr[5] = 0xFF;
	qstruct->retries = ARP_MAXRETRY;
	qstruct->ttl = ARP_RESEND;
	arpsendreq( i );
	qstruct->state = ARP_PENDING;				/* Waiting for Reply	*/

	return 0;

}


/******************************************************************************
Function:		arp_keepcache

Parameters:		UINT32 pra - ip address to be held on cache

Return val:		INT16 0 - OK
					  (-1) - Not OK

Date:			02.4.2003

Desc:			Tries to keep given dynamic IP on cache. Notice that there is no
				guarantee for that because round robin cache replacement may
				override the entry.
				This function is best suitable for keeping ARP for TCP connections
				by calling it periodically.
*******************************************************************************/

INT16 arp_keepcache (UINT32 pra)
{

	struct arpentry *qstruct;
	INT8 i;

	DEBUGOUT("Trying to keep IP on cache\r\n");

	/* Is the address in the cache	*/

	for( i=0; i<ARP_TSIZE; i++ )
	{
		qstruct = &arptable[i];

		if( qstruct->state == ARP_FREE )
			continue;

		if( qstruct->state < ARP_RESOLVED )
			continue;

		if( qstruct->pradr == pra)
		{
			/* The address is in cache, is it valid? */

			if( qstruct->type != ARP_TEMP_IP )
				return(-1);

			/* Is it time to start refrsh the entry?	*/

			if( qstruct->ttl <= (ARP_RESEND * 2) )
				qstruct->state = ARP_REFRESHING;

			/* All OK	*/

			DEBUGOUT("Keeping address on cache\r\n");

			return(0);
		}

	}

	return(-1);


}

/******************************************************************************
Function:		arpmanage

Parameters:		none

Return val:		void

Date:			04.11.2001

Desc:			Iterate through ARP cache aging entries. If timed-out entry is
				found, remove it (dynamic address) or update it
				(static address). This function MUST be called periodically by
				system.
*******************************************************************************/

void arpmanage (void)
{
	struct arpentry *qstruct;
	UINT8 i,j;
	static UINT8 aenext=0;

	/* Check Timer before entering	*/

	if( check_timer(ArpTimer) )
		return;

	init_timer( ArpTimer, ARP_MANG_TOUT*TIMERTIC);

	//DEBUGOUT("Managing ARP Cache\n\r");

	for( i=0; i<ARP_TSIZE; i++ )
	{
		//DEBUGOUT(".");

		qstruct = &arptable[aenext];

		j = aenext;

		/* Take next entry next time	*/

		aenext++;
		if(aenext >= ARP_TSIZE)
			aenext = 0;

		if( qstruct->state == ARP_FREE )
			continue;

		/* TODO: How about ARP_RESERVED?	*/

		if( qstruct->ttl > 0 )				/* Aging		*/
			qstruct->ttl --;

		if( qstruct->ttl == 0 )				/* Timed Out?	*/
		{
			/* Do it for temporay entries	*/

			DEBUGOUT("Found Timed out Entry..\n\r");

			if( qstruct->type == ARP_TEMP_IP )
			{
				/* Release it?	*/
				if( qstruct->state == ARP_RESOLVED )
				{
					DEBUGOUT("Releasing ARP Entry..\n\r");
					qstruct->state = ARP_FREE;
					continue;
				}

				/* Decrease retries left	*/

				if( qstruct->retries > 0 )
					qstruct->retries--;

				if( qstruct->retries == 0 )
				{
					DEBUGOUT("ARP Replies Used up, releasing entry..\n\r");
					qstruct->state = ARP_FREE;
					continue;
				}

				/* So we need to resend ARP request	*/

				DEBUGOUT("Trying to Resolve dynamic ARP Entry..\n\r");

				qstruct->ttl = ARP_RESEND;
				arpsendreq( j );

				if(qstruct->state != ARP_REFRESHING)
					qstruct->state = ARP_PENDING;				/* Waiting for Reply	*/

				return;

			}

			/* Do it for Static Entries			*/

			if( qstruct->type == ARP_FIXED_IP )
			{

				/* So we need to resend ARP request	*/

				/* Do not try to refresh broadcast	*/

				if(qstruct->pradr == IP_BROADCAST_ADDRESS)
				{
					qstruct->ttl = ARP_TIMEOUT;
					continue;
				}

				DEBUGOUT("Refreshing Static ARP Entry..\n\r");

				if( qstruct->retries > 0 )
					qstruct->retries--;

				if( qstruct->retries == 0 )
					qstruct->state = ARP_PENDING;
				else
					qstruct->state = ARP_REFRESHING;

				qstruct->ttl = ARP_RESEND;

				arpsendreq( j );

				return;

			}

		}

	}


}




/******************************************************************************
Function:		arpinit

Parameters:		none

Return val:		none

Date:			01.11.2001

Desc:			Initialize data structures for ARP processing
*******************************************************************************/

void arpinit (void)
{
	struct arpentry *qstruct;
	INT8 i;

	DEBUGOUT("Initializing ARP");

	for( i=0; i<ARP_TSIZE; i++ )
	{
		qstruct = &arptable[i];

		qstruct->state = ARP_FREE;
		qstruct->type = ARP_TEMP_IP;

		DEBUGOUT(".");

	}

	ArpTimer = get_timer();
	init_timer(ArpTimer, ARP_MANG_TOUT*TIMERTIC);

	/* set broadcast entry	*/

	qstruct = &arptable[0];
	qstruct->pradr = IP_BROADCAST_ADDRESS;
	qstruct->state = ARP_RESOLVED;
	qstruct->type = ARP_FIXED_IP;
	qstruct->ttl = ARP_TIMEOUT;
	qstruct->retries = ARP_MAXRETRY;

	for(i=0; i<MAXHWALEN; i++)
		qstruct->hwadr[i] = 0xFF;

	DEBUGOUT("\n\r");

}

/******************************************************************************
Function:		IsSub

Parameters:		UINT32 ipadr - IP address under check
				struct netif *machine - pointer to config. of network
										     interface used

Return val:		1 - ipadr belongs to subnet of given machine
				0 - ipadr is NOT a part of subnet on given machine

Date:			05.11.2001

Desc:			Checks if the given IP address belongst to subnet of given
				machine.
*******************************************************************************/

UINT8 IsSub (LWORD ipadr, struct netif* machine)
{

	UINT32 ltemp;

	ltemp = ipadr & machine->netmask;						/* Get Subnet part	*/

	ltemp ^= (machine->localip & machine->netmask);			/* Compare to my IP	*/

	if( ltemp )
		return(0);

	return(1);

}

⌨️ 快捷键说明

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