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

📄 arp.c.svn-base

📁 数字广播系统的开发源码
💻 SVN-BASE
字号:
/*
 */

#include "GloblDef.h"
#include "TCPIPmem.h"
#include "IP.h"
#include "etherif.h"
#include "ARP.h"
#include "Netif.h"

unsigned char xdata EtherAddrAny[ETHER_ADDR_LEN] = {0xff,0xff,0xff,0xff,0xff,0xff};

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

/* arp init */
void ARPInit() reentrant
{
	unsigned char 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 xdata * ARPQuery(struct SNetIf xdata *NetIf,IP_ADDR DestIP) reentrant
{
	struct SMemHead xdata *MemHead;
	struct SEtherHead xdata *EtherHead;
	struct SARPPacket xdata *ARPPacket;

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

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

	/* fill Ether head */
	MemCopy(EtherHead->DestAddr,EtherAddrAny,ETHER_ADDR_LEN);
	MemCopy(EtherHead->ScrAddr ,
		((struct SEtherDevice xdata *)(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(ARPPacket->EtherDestAddr,EtherAddrAny,ETHER_ADDR_LEN);
	MemCopy(ARPPacket->EtherScrAddr,
		((struct SEtherDevice xdata *)(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 xdata *ARPInput(struct SMemHead xdata *MemHead, struct SNetIf xdata *NetIf) reentrant
{
	struct SEtherHead xdata *EtherHead;
	struct SARPPacket xdata *ARPPacket;

	EtherHead = (struct SEtherHead xdata *)(MemHead->pStart);
	ARPPacket = (struct SARPPacket xdata *)(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(EtherHead->DestAddr,ARPPacket->EtherScrAddr,ETHER_ADDR_LEN);
			MemCopy(EtherHead->ScrAddr,
				((struct SEtherDevice xdata *)(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(ARPPacket->EtherDestAddr,ARPPacket->EtherScrAddr,
				(sizeof(IP_ADDR) + ETHER_ADDR_LEN));

			/* fill source part. include Ether addr and Ip addr*/
			ARPPacket->IPScrAddr = NetIf->IPAddr;
			MemCopy(ARPPacket->EtherScrAddr,
				((struct SEtherDevice xdata *)(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 xdata *ARPPacket) reentrant
{
	unsigned char i;
	unsigned int MinTime;
	unsigned char 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(ARPTable[iToReplace].EtherAddr,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 */
unsigned char ARPFind(unsigned char EtherAddr[],IP_ADDR IPAddr) reentrant
{
	unsigned char 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() reentrant
{
	unsigned char 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 + -