📄 arp.c.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 + -