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

📄 arp.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 "etherif.h"
#include "ip.h"
#include "netif.h"
#include "arp.h"
#include "utilities.h"

BYTE   EtherAddrAny[ETHER_ADDR_LEN] = {0xff,0xff,0xff,0xff,0xff,0xff};

/* entry table */
struct SARPEntry   ARPTable[ARP_ENTRY_MAX_NUM];

/* arp init */
void ARPInit()  
{
	BYTE i;

	/* set every unit in arp tabel invalid */
	for(i = 0; i < ARP_ENTRY_MAX_NUM; i++)
		ARPTable[i].time = 0;
}

/* construct a arp query packet and return it */
struct SMemHead   * ARPQuery(struct SNetIf   *NetIf,IP_ADDR DestIP)  
{
	struct SMemHead   *MemHead;
	struct SEtherHead   *EtherHead;
	struct SARPPacket   *ARPPacket;

	/* allocate a packet mem */
	if((MemHead = MemAllocate(sizeof(struct SARPPacket) + 
		sizeof(struct SEtherHead))) == NULL)
		return NULL;
	
	EtherHead = (struct SEtherHead   *)(MemHead->pStart);
	ARPPacket = (struct SARPPacket   *)(MemHead->pStart + 
		sizeof(struct SEtherHead));

	/* fill Ether head */
	MemCopy((void*)EtherHead->DestAddr,EtherAddrAny,ETHER_ADDR_LEN);
	MemCopy((void*)EtherHead->ScrAddr ,
		((struct SEtherDevice   *)(NetIf->Info))->Addr,ETHER_ADDR_LEN);
	EtherHead->type = htons(ETHER_TYPE_ARP);

	/* fill arp head */
	ARPPacket->HardWareAddrLen	= ARP_HARDWARE_ADDR_LEN_ETHER;
	ARPPacket->HardwareType		= htons(ARP_HARDWARE_TYPE_ETHER);
	ARPPacket->ProtocolAddrLen	= ARP_PROTOCOL_ADDR_LEN_IP;
	ARPPacket->ProtocolType		= htons(ARP_PROTOCOL_TYPE_IP);
	ARPPacket->type				= htons(ARP_TYPE_ARP_REQUEST);

	/* fill arp content */
	ARPPacket->IPDestAddr	= DestIP;
	ARPPacket->IPScrAddr	= NetIf->IPAddr;
	MemCopy((void*)ARPPacket->EtherDestAddr,EtherAddrAny,ETHER_ADDR_LEN);
	MemCopy((void*)ARPPacket->EtherScrAddr,
		((struct SEtherDevice   *)(NetIf->Info))->Addr,ETHER_ADDR_LEN);

	return MemHead;
}

/* deel with a input arp packet. if send a reply is needed return 
this replay packet, oterhwise return NULL  */
struct SMemHead   *ARPInput(struct SMemHead   *MemHead, struct SNetIf   *NetIf)  
{
	struct SEtherHead   *EtherHead;
	struct SARPPacket   *ARPPacket;

	EtherHead = (struct SEtherHead   *)(MemHead->pStart);
	ARPPacket = (struct SARPPacket   *)(MemHead->pStart + 
		sizeof(struct SEtherHead));

	/* which type of arp */
	switch(ntohs(ARPPacket->type))
	{
	case ARP_TYPE_ARP_REQUEST:

		/* if arp request to local host */
		if(ARPPacket->IPDestAddr == NetIf->IPAddr)
		{
			/* send arp replay */

			/* fill Ether head */
			MemCopy((void*)EtherHead->DestAddr,(void*)ARPPacket->EtherScrAddr,ETHER_ADDR_LEN);
			MemCopy((void*)EtherHead->ScrAddr,
				(void*)((struct SEtherDevice   *)(NetIf->Info))->Addr,ETHER_ADDR_LEN);
			EtherHead->type = htons(ETHER_TYPE_ARP);

			/* copy source part to dest part. include Ether addr and 
			Ip addr */
			MemCopy((void*)(void*)ARPPacket->EtherDestAddr,(void*)ARPPacket->EtherScrAddr,
				(sizeof(IP_ADDR) + ETHER_ADDR_LEN));

			/* fill source part. include Ether addr and Ip addr*/
			ARPPacket->IPScrAddr = NetIf->IPAddr;
			MemCopy((void*)ARPPacket->EtherScrAddr,
				((struct SEtherDevice   *)(NetIf->Info))->Addr,ETHER_ADDR_LEN);

			/* arp type */
			ARPPacket->type = htons(ARP_TYPE_ARP_REPLY);

			return MemHead;
		}
		break;

	case ARP_TYPE_ARP_REPLY:
		/* add to arp table */
		ARPAddEntry(ARPPacket);
		break;
	}
				
	/* for any case except ARP_TYPE_ARP_REQUEST for this IP, 
	arp packet is released */
	MemFree(MemHead);

	/* no packet need send */
	return NULL;
}

/* add a entry to arp table */
void ARPAddEntry(struct SARPPacket   *ARPPacket)  
{
	BYTE i;
	WORD MinTime;
	BYTE iToReplace;	/* index of entry going to be replace */

	/* find a free entry */
	for(i = 0; i<ARP_ENTRY_MAX_NUM; i++)
	{
		if(ARPTable[i].time == 0)
		{
			iToReplace = i;
			break;
		}
	}

	/* if no free entry, find the oldest entry */
	if(i == ARP_ENTRY_MAX_NUM)
	{	
		for(i = 0, MinTime = ARP_ENTRY_TIME_OUT, iToReplace = 0;
			i<ARP_ENTRY_MAX_NUM; i++)
		{
			if(MinTime > ARPTable[i].time)
			{
				MinTime = ARPTable[i].time;
				iToReplace = i;
			}
		}
	}

	/* replace the entry */
	MemCopy((void*)ARPTable[iToReplace].EtherAddr,(void*)ARPPacket->EtherScrAddr,
		ETHER_ADDR_LEN);
	ARPTable[iToReplace].IPAddr = ARPPacket->IPScrAddr;

	/* start timer */
	ARPTable[iToReplace].time = ARP_ENTRY_TIME_OUT;
}

/* find IPAddr in arptable copy it to EtherAddr. if can't find return
false */
BOOL ARPFind(BYTE EtherAddr[],IP_ADDR IPAddr)  
{
	BYTE i;
	for(i = 0; i<ARP_ENTRY_MAX_NUM; i++)
	{
		/* check only valid entry */
		if(ARPTable[i].time != 0)
		{
			if(ARPTable[i].IPAddr == IPAddr)
			{
				MemCopy(EtherAddr,ARPTable[i].EtherAddr,ETHER_ADDR_LEN);
				return TRUE;
			}
		}
	}
	return FALSE;
}

void ARPTimer()  
{
	BYTE i;

	/* decrease every entry timer */
	for(i = 0; i<ARP_ENTRY_MAX_NUM; i++)
	{
		/* check only valid entry */
		if(ARPTable[i].time != 0)
		{
			ARPTable[i].time--;
		}
	}
}

⌨️ 快捷键说明

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