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

📄 arp.c

📁 S3C2440驱动DM9000A的裸机程序
💻 C
字号:
#include "MyLib.h"

extern struct _CONN conn[MAX_CONN+1];//tcpdata.c
struct{
	U8  ipaddr[4];
   U8  hwaddr[6];
   U16 timer;
}Arp_cache[CACHESIZE];

void Arp_init(void)
{
	netlock=gSendUDP=0;
	//gMyIP[0]=192;  gMyIP[1]=168;  gMyIP[2]=0;  gMyIP[3]=201;	// 192.168.0.201
	gUDP_counter=0;  gUDP_Port=0x1111;  gIP_ident=0;
	MyMemset(Arp_cache, 0, sizeof(Arp_cache));
	MyMemset(conn, 0, sizeof(conn));
}

void Refresh_Arp_cache(void)				// 每60秒刷新一次ARP_CACHE
{
	U32 i;
	for(i=0; i<CACHESIZE; i++){
		if((Arp_cache[i].ipaddr[0]!=0)&&(Arp_cache[i].timer)){
			Arp_cache[i].timer--;
			if(Arp_cache[i].timer==0)
				MyMemset(&Arp_cache[i].ipaddr[0], 0, 4);
		}
	}
}

void Arp_update(U8 *ipaddr, U8 *hwaddr)
{
	U16 i, cached, oldest, minimum;
	cached=0;
	for(i=0; i<CACHESIZE; i++){			// 查找并更新CACHE中的内容
		if(!MyMemcmp(&Arp_cache[i].ipaddr[0], ipaddr, 4)){
			MyMemcpy(&Arp_cache[i].hwaddr[0], hwaddr, 6);
			Arp_cache[i].timer=CACHETIME;
			cached=1;
         break;
      }
   }
	if(cached==0){								// 没有找到
		for(i=0; i<CACHESIZE; i++){		// 在CACHE中找出一个空位置并保存
			if(Arp_cache[i].ipaddr[0]==0){
				MyMemcpy(&Arp_cache[i].ipaddr[0], ipaddr, 4);
				MyMemcpy(&Arp_cache[i].hwaddr[0], hwaddr, 6);
				Arp_cache[i].timer=CACHETIME;
				cached=1;
				break;
			}
		}
		if(cached==0){							// 没有空位置,替换最旧的一个
			minimum=0xFFFF;
			for(i=0; i<CACHESIZE; i++){
				if(Arp_cache[i].timer<minimum){
					minimum = Arp_cache[i].timer;
					oldest = i;
				}
			}
			MyMemcpy(&Arp_cache[oldest].ipaddr[0], ipaddr, 4);
			MyMemcpy(&Arp_cache[oldest].hwaddr[0], hwaddr, 6);
			Arp_cache[oldest].timer=CACHETIME;
		}
	}
}

void Arp_send(U8 *hwaddr, U8 *ipaddr, U16 type)
{
	U8 buf[60];									// arp数据包长度=42,网络数据包最小长度=60
	U32 i;
	MyMemcpy(buf+6, gMyPhy, 6);			// 发送网卡物理地址
	*(U16*)(buf+0x0C)=ARP_PACKET;			// ARP ethernet package
	*(U16*)(buf+0x0E)=0x0100;				// Hardware type
	*(U16*)(buf+0x10)=IP_PACKET;			// Protocol type
	*(U16*)(buf+0x12)=0x0406;				// ARP type
	*(U16*)(buf+0x14)=type;					// ARP request type
	MyMemcpy(buf+0x16, gMyPhy, 6);		// 发送网卡物理地址
	MyMemcpy(buf+0x1C, gMyIP, 4);			// 发送网卡IP
	if(type==ARP_REQUEST){
		MyMemset(buf, 0, 6);					// 接收网卡物理地址为空
		MyMemset(buf+0x20, 0, 6);			// 接收网卡物理地址为空
	}else{
		if(hwaddr==NULL){
			MyMemset(buf, 0, 6);				// 接收网卡物理地址
			MyMemset(buf+0x20, 0, 6);		// 接收网卡物理地址
		}else{
			MyMemcpy(buf, hwaddr, 6);		// 接收网卡物理地址
			MyMemcpy(buf+0x20, hwaddr, 6);// 接收网卡物理地址
		}
	}
	MyMemcpy(buf+0x26, ipaddr, 4);		// 接收网卡IP
	for(i=0; i<18; i++)
		buf[i+0x2A]=' ';						// 后面填充空格
	DM9000_SendBuf(buf, 60);
}

U8 *Arp_resolve(U8 *ipaddr)				// 通过IP地址查找网卡物理地址
{
	U32 i;
	for(i=0; i<CACHESIZE; i++){			// 先在CACHE中查找
		if(!MyMemcmp(&Arp_cache[i].ipaddr[0], ipaddr, 4))
			return(&Arp_cache[i].hwaddr[0]);
	}
	Arp_send(NULL, ipaddr, ARP_REQUEST);// 不在CACHE中则发送ARP请求
	return(NULL);
}

void Arp_receive(U8 *buf)
{
	if(*(U16*)(buf+0x0E)!=0x0100 || *(U16*)(buf+0x10)!=IP_PACKET || MyMemcmp(buf+0x26, gMyIP, 4))
		return;
	Arp_update(buf+0x1C, buf+0x06);
	if(*(U16*)(buf+0x14)==ARP_REQUEST){
		Arp_send(buf+6, buf+0x1C, ARP_RESPONSE);
	}
}

⌨️ 快捷键说明

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