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