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

📄 arp.c

📁 opentcp_mcf5282原代码
💻 C
📖 第 1 页 / 共 2 页
字号:
/*********************************************************************************
File:			arp.c

Date:

Version:		0.1

Author:			Jari Lahti (jari.lahti@violasystems.com)

Description:	arp (address resolution protocol) functions

Version Info:

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

#include "opentcp.h"



//extern UINT8	RemoteEthernet[]; 		//Host Ethernet Address
//extern UINT32	IP_RemoteAdd;			//Remote IP Address
//extern UINT32	IP_LocalAdd;			//My IP address

struct arpentry	arptable[ARP_TSIZE];

UINT8 ArpTimer;


UINT8 Process_ARP (struct otcp_ethframe* frame)
{
	/* Checks received Ethernet Frame to see if it's an ARP */
	/* If valid ARP response, updates ARP cache				*/
	/* If ARP request, sends response						*/
	/* Return values: FALSE = No ARP, TRUE = Was ARP		*/
	/* if ARP detected, upper layer protocols must skip it  */

	UINT8 temp;

	/* Check if ARP packet*/

	if( frame->protocol == ARP_ETHCODE )
	{
		/* Yep, ARP */

		NETWORK_RECEIVE_INITIALIZE(frame->bufindex);

		/* Is it long enough?	*/

		if( frame->framesize < (2*MAXHWALEN + 2*MAXPRALEN + 2 + 6) )
		{
			/* Somehow corrupted ARP packet	*/
			DEBUGOUT("Corrupted ARP packet\n\r");
			NETWORK_RECEIVE_END();
			return(TRUE);

		}

		/* Ignore next 6 bytes: <HW type>, <Protocol type> */
		/* <HW address len> and <Protocol address len> 	   */

		for(temp=0; temp<6; temp++)
			RECEIVE_NETWORK_B();

		DEBUGOUT("Incoming ARP..\n\r");

		/* Check if request or response */

		if( RECEIVE_NETWORK_B() == 0x00)
		{

			temp = RECEIVE_NETWORK_B();					//get opcode

			//debugout(temp);

			if( temp == ARP_REQUEST )
			{
				DEBUGOUT(" ARP REQUEST Received..\n\r");
				ARPSendResponse();
			}
			else if( temp == ARP_REPLY )
			{
				DEBUGOUT("ARP Response Received..\n\r");
				ARPGetResponse();
			}

		/* Wasn't request or response or all done, dump it */

		}


		//NETWORK_RECEIVE_END();
		return(TRUE);

	}

	/* Wasn't ARP, don't touch the packet */

	return(FALSE);
}


void ARPSendResponse(void)
{
	UINT8 rem_hwadr[MAXHWALEN];
	UINT32 rem_ip;
	UINT32 ltemp;
	UINT8 i;

	/* Record Sender's HW address		*/

	for( i=0; i < MAXHWALEN; i++ )
		rem_hwadr[i] = RECEIVE_NETWORK_B();

	/* Read Sender's IP Address	*/

	rem_ip = 0;
	for( i=0; i<MAXPRALEN; i++)
	{
		rem_ip <<= 8;
		rem_ip |= RECEIVE_NETWORK_B();
	}


	/* Skip Target HW address		*/

	RECEIVE_NETWORK_B();
	RECEIVE_NETWORK_B();
	RECEIVE_NETWORK_B();
	RECEIVE_NETWORK_B();
	RECEIVE_NETWORK_B();
	RECEIVE_NETWORK_B();

	/* Is The Packet For Us?	*/

	ltemp = 0;
	for( i=0; i<MAXPRALEN; i++)
	{
		ltemp <<= 8;
		ltemp |= RECEIVE_NETWORK_B();
	}


	if( ltemp != localmachine.localip )
	{
		return;								/* No	*/
	}

	DEBUGOUT("Preparing for ARP Reply\n\r");


	/* OK. Now send reply		*/

	NETWORK_SEND_INITIALIZE(TXBUF_ENET);

	/* Add datalink (Ethernet addresses) information	*/

	for( i=0; i<MAXHWALEN; i++)
	{
		otcp_txframe.destination[i] = rem_hwadr[i];
	}

	for( i=0; i<MAXHWALEN; i++)
	{
		otcp_txframe.source[i] = localmachine.localHW[i];
	}

	otcp_txframe.protocol = PROTOCOL_ARP;

	NETWORK_ADD_DATALINK(&otcp_txframe);

	/* PUT ARP Data	*/

	SEND_NETWORK_B( (BYTE)(AR_HARDWARE>>8) );				/* Hardware Type	*/
	SEND_NETWORK_B( (BYTE)AR_HARDWARE );
	SEND_NETWORK_B(0x08);									/* Protocol Type	*/
	SEND_NETWORK_B(0x00);
	SEND_NETWORK_B(MAXHWALEN);								/* HW Adr Len		*/
	SEND_NETWORK_B(MAXPRALEN);								/* Protocol Adr. Len*/
	SEND_NETWORK_B( 0x00 );									/* ARP Opcode		*/
	SEND_NETWORK_B( 0x02 );
	SEND_NETWORK_B((UINT8)(localmachine.localHW[0]));		/* Address fields	*/
	SEND_NETWORK_B((UINT8)(localmachine.localHW[1]));
	SEND_NETWORK_B((UINT8)(localmachine.localHW[2]));
	SEND_NETWORK_B((UINT8)(localmachine.localHW[3]));
	SEND_NETWORK_B((UINT8)(localmachine.localHW[4]));
	SEND_NETWORK_B((UINT8)(localmachine.localHW[5]));
	SEND_NETWORK_B((UINT8)(localmachine.localip>>24));
	SEND_NETWORK_B((UINT8)(localmachine.localip>>16));
	SEND_NETWORK_B((UINT8)(localmachine.localip>>8));
	SEND_NETWORK_B((UINT8)(localmachine.localip));
	SEND_NETWORK_B((UINT8)rem_hwadr[0]);
	SEND_NETWORK_B((UINT8)rem_hwadr[1]);
	SEND_NETWORK_B((UINT8)rem_hwadr[2]);
	SEND_NETWORK_B((UINT8)rem_hwadr[3]);
	SEND_NETWORK_B((UINT8)rem_hwadr[4]);
	SEND_NETWORK_B((UINT8)rem_hwadr[5]);
	SEND_NETWORK_B((UINT8)(rem_ip>>24));
	SEND_NETWORK_B((UINT8)(rem_ip>>16));
	SEND_NETWORK_B((UINT8)(rem_ip>>8));
	SEND_NETWORK_B((UINT8)rem_ip);

	NETWORK_COMPLETE_SEND(0x0040);		/* Send the packet	*/

	DEBUGOUT("ARP Reply Sent..\n\r");

	/* Add the Sender's info to cache because we can	*/

	arpadd(rem_ip, &otcp_txframe.destination[0], ARP_TEMP_IP);

	return;

}

void ARPGetResponse(void)
{
	struct arpentry *qstruct;
	UINT8 rem_hwadr[MAXHWALEN];
	UINT32 	rem_ip;
	UINT32 	ltemp;
	UINT8 i;
	UINT8 j;

	/* Read Sender's HW address	*/

	for( i=0; i < MAXHWALEN; i++ )
		rem_hwadr[i-1] = RECEIVE_NETWORK_B();

	/* Read Sender's IP Address	*/

	rem_ip = 0;
	for( i=0; i<MAXPRALEN; i++)
	{
		rem_ip <<= 8;
		rem_ip |= RECEIVE_NETWORK_B();
	}


	/* Skip our HW Address	*/

	for(i=0; i<MAXHWALEN; i++)
		RECEIVE_NETWORK_B();


	/* Is The Packet For Us?	*/

	ltemp = 0;
	for( i=0; i<MAXPRALEN; i++)
	{
		ltemp <<= 8;
		ltemp |= RECEIVE_NETWORK_B();
	}


	if( ltemp != localmachine.localip )
		return;								/* No	*/


	DEBUGOUT("Now entering to process ARP Reply..\n\r");

	/* Are we waiting for that reply?	*/

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

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

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

		if( rem_ip == qstruct->pradr )
		{
			/* We are caching that IP, refresh it	*/

			DEBUGOUT("Refreshing ARP cache from Reply..\n\r");

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

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

			/* Done	*/

			break;
		}

	}

}


/******************************************************************************
Function:		arpsendreq

Parameters:		UINT8 entry - Entry to ARP table

Return val:		none

Date:			01.11.2001

Desc:			Send ARP request of given entry
*******************************************************************************/

void arpsendreq (UINT8 entry)
{
	struct arpentry *qstruct;
	UINT8 i;

	qstruct = &arptable[entry];

	NETWORK_SEND_INITIALIZE(TXBUF_ENET);

	/* Add datalink (Ethernet addresses) information	*/

	for( i=0; i<MAXHWALEN; i++)
	{
		otcp_txframe.destination[i] = 0xFF;
	}

	for( i=0; i<MAXHWALEN; i++)
	{
		otcp_txframe.source[i] = localmachine.localHW[i];
	}

	otcp_txframe.protocol = PROTOCOL_ARP;


	NETWORK_ADD_DATALINK(&otcp_txframe);

	/* PUT ARP Data	*/

	SEND_NETWORK_B( (BYTE) (AR_HARDWARE>>8) );			/* Hardware Type	*/
	SEND_NETWORK_B( (BYTE) AR_HARDWARE );
	SEND_NETWORK_B(0x08);								/* Protocol Type	*/
	SEND_NETWORK_B(0x00);
	SEND_NETWORK_B(MAXHWALEN);							/* HW Adr Len		*/
	SEND_NETWORK_B(MAXPRALEN);							/* Protocol Adr. Len*/
	SEND_NETWORK_B( (BYTE)(ARP_REQUEST>>8));			/* ARP Opcode		*/
	SEND_NETWORK_B( (BYTE) ARP_REQUEST );
	SEND_NETWORK_B((UINT8)localmachine.localHW[0]);		/* Address fields	*/
	SEND_NETWORK_B((UINT8)localmachine.localHW[1]);
	SEND_NETWORK_B((UINT8)localmachine.localHW[2]);
	SEND_NETWORK_B((UINT8)localmachine.localHW[3]);
	SEND_NETWORK_B((UINT8)localmachine.localHW[4]);
	SEND_NETWORK_B((UINT8)localmachine.localHW[5]);
	SEND_NETWORK_B((UINT8)(localmachine.localip>>24));
	SEND_NETWORK_B((UINT8)(localmachine.localip>>16));
	SEND_NETWORK_B((UINT8)(localmachine.localip>>8));
	SEND_NETWORK_B((UINT8)localmachine.localip);
	SEND_NETWORK_B((UINT8)0xFF);
	SEND_NETWORK_B((UINT8)0xFF);
	SEND_NETWORK_B((UINT8)0xFF);
	SEND_NETWORK_B((UINT8)0xFF);
	SEND_NETWORK_B((UINT8)0xFF);
	SEND_NETWORK_B((UINT8)0xFF);
	SEND_NETWORK_B((UINT8)(qstruct->pradr>>24));
	SEND_NETWORK_B((UINT8)(qstruct->pradr>>16));
	SEND_NETWORK_B((UINT8)(qstruct->pradr>>8));
	SEND_NETWORK_B((UINT8)qstruct->pradr);


	/* Packet assembled now, just send it ... */

	NETWORK_COMPLETE_SEND(0x0040);						/* Min packet size	*/

 	DEBUGOUT("ARP Request Sent\n\r");

}



/******************************************************************************
Function:		arpalloc

Parameters:		UINT8 type - type of ARP entry

Return val:		positive - pointer to allocated arp entry
				(-1) - entry not found (entries used up)

Date:			01.11.2001

Desc:			Allocate arp entry for given type. Chooses the unused entry if
				one exists. Otherwice deletes entries in round-robin fashion.
				Static entries are not deleted/reallocated.
*******************************************************************************/

INT8 arpalloc (UINT8 type)
{
	struct arpentry *qstruct;
	INT8 i;
	static UINT8 aenext = 1;		/* Cache Manager	*/
	INT16 found;


	/* Try to find free entry	*/

	found = -1;

	for( i=0; i<ARP_TSIZE; i++ )
	{

		if( arptable[i].state == ARP_FREE )
		{
			found = i;
			break;
		}

	}

	if(found != (-1) )
	{
		qstruct = &arptable[found];
		qstruct->state = ARP_RESERVED;
		qstruct->type = type;
		return( (UINT8)found );
	}

	/* if no success, try ro find first temporary entry	*/
	/* on round-robin fashion							*/


	for( i=0; i<ARP_TSIZE; i++ )
	{
		if( arptable[aenext].type == ARP_TEMP_IP)
		{
			found = aenext;
			break;
		}

		/* Move to next entry */

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

	}


	/* Was there free or temporary entries?	*/

	if( found == (-1) )
		return(-1);

	/* Next time start from next entry	*/

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

	qstruct = &arptable[found];

	/* Set ARP initial parameters	*/

	qstruct->state = ARP_RESERVED;
	qstruct->type = type;

	/* Was return(i)!!! <-wrong!!	*/

	return((UINT8)found);

}

/******************************************************************************
Function:		arpadd

Parameters:		UINT32 pra - protocol address
				UINT8* hwadr - Ethernet MAC address (6 bytes)
				UINT8 type - type of address allocated if not found

Return val:		INT8 (-1) - Not succesful (no ARP entries)
						0 - Address already in cache, refreshed
						1 - New entry created

Date:			10.7.2002

Desc:			Add given IP address and MAC address to ARP cache
*******************************************************************************/

INT8 arpadd (UINT32 pra, UINT8* hwadr, UINT8 type)
{
	struct arpentry *qstruct;
	INT8 i;
	INT8 j;

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

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

		if( (qstruct->pradr == pra) && (pra != IP_BROADCAST_ADDRESS))
		{
			/* The address is in cache, refresh it	 */

⌨️ 快捷键说明

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