📄 arp.c
字号:
#define ARP_ENTITY
/*
************************************************
*
* arp.c
*
* 网络层实现arp协议,建立在internet层协议之上
* 1.维护本机的arp表项
* 2.请求和应答arp
*
************************************************
*/
#include "includes.h"
a_t My_Arp[MAX_ARP_NUM];
a_t My_GateArp={
0x00, //有效时间
MY_Gate_IP_Arp
0x00,0x00,0x00,0x00,0x00,0x00
};
static INT8U ARP_REQ_MAC[]={0xff,0xff,0xff,0xff,0xff,0xff};
/*
******************************************
*函数:void Init_Arp(void)
*功能:
* arp表的初始化函数
* 初始化时调用,用来清空arp表向
*
*
******************************************
*/
void Init_Arp(void)
{
INT8U i,j;
for(i=0;i<MAX_ARP_NUM;i++)
{
My_Arp[i].TTL=0x00;
for(j=0;j<4;j++)
{
My_Arp[i].IP_NUM[j]=0x00;
}
for(j=0;j<6;j++)
{
My_Arp[i].MAC_NUM[j]=0x00;
}
}
}
/*
****************************************
*函数:void Arp_Request(INT8U *ipaddr)
*功能:
* 发送arp请求
*参数:
* ipaddr 需要请求的ip地址
*
****************************************
*/
void Arp_Request(INT8U *ipaddr)
{
_pkst TxArpReq;
arp * parp;
INT8U ArpBuff[46]; //缓存arp
INT8U i;
parp=(arp *)ArpBuff;
//复制硬件地址,本机和目标机,目标机的为0x00
for(i=0;i<6;i++)
{
parp->SrcMacAdd[i]=My_Mac[i];
parp->DestMacAdd[i]=0x00;
}
for(i=0;i<4;i++)
{
parp->SrcIpAdd[i]=My_Ip[i];
parp->DestIpAdd[i]=ipaddr[i];
}
parp->HardwareType=0x0100;
parp->ProtocalType=0x0008;
parp->HardwareLen=0x06;
parp->ProtocalLen=0x04;
parp->Opration=0x0100;
ArpBuff[28]=0x00;
TxArpReq.next=NULL;
TxArpReq.length=46;
TxArpReq.pdata=ArpBuff;
Send_ethernet_Frame(&TxArpReq,ARP_REQ_MAC,ARP_PACKED);
return;
}
/*
*************************************************
*函数:void PROCESS_ARP_REC(INT8U *ARP_PTR)
*功能:
* 处理接收到的arp包
* 1.arp请求报的处理
* 2.arp应答包的处理
*参数:
* 接收到的数据的气势指针
*
*
************************************************
*/
void PROCESS_ARP_REC(INT8U *ARP_PTR)
{
arp * parp;
parp=(arp*)ARP_PTR;
if(parp->Opration==0x0100) //请求报
{
Arp_Answer(ARP_PTR);
}
else if(parp->Opration==0x0200)
{
REC_ARP_REQ(ARP_PTR); //应答包
}
}
/*
*************************************************
*函数:INT8U REC_ARP_REQ(INT8U *ARP_REC_PTR)
*功能:
* 本报为本机之前发送的arp请求报的到的应答包
* 本机由此应答包来更新arp表项
*
*参数:
* 指向接收的数据指针
*
*
*************************************************
*/
INT8U REC_ARP_REQ(INT8U *arp_data)
{
INT8U i,j;
arp *parp;
parp=(arp*)arp_data; //
if(parp->SrcIpAdd[0]==My_GateArp.IP_NUM[0])
if(parp->SrcIpAdd[1]==My_GateArp.IP_NUM[1])
if(parp->SrcIpAdd[2]==My_GateArp.IP_NUM[2])
if(parp->SrcIpAdd[3]==My_GateArp.IP_NUM[3]) //是网管
{
for(i=0;i<6;i++)
{
My_GateArp.MAC_NUM[i]=parp->SrcMacAdd[i];
}
My_GateArp.TTL=100;
return 1;
}
if(parp->SrcIpAdd[0]==My_Ip[0])
if(parp->SrcIpAdd[1]==My_Ip[1])
if(parp->SrcIpAdd[2]==My_Ip[2]) //属于本接口的子网
{
for(i=0;i<MAX_ARP_NUM;i++)
{
if(parp->SrcIpAdd[0]==My_Arp[i].IP_NUM[0])
if(parp->SrcIpAdd[1]==My_Arp[i].IP_NUM[1])
if(parp->SrcIpAdd[2]==My_Arp[i].IP_NUM[2])
if(parp->SrcIpAdd[3]==My_Arp[i].IP_NUM[3]) //查到该arp表项,更新
{
My_Arp[i].TTL=100;
return 0;
}
}
//需要添加一项arp表木
for(i=0;i<MAX_ARP_NUM;i++)
{
if(My_Arp[i].TTL==0)
{
//找到一个空的记录项
for(j=0;j<4;j++)
{
My_Arp[i].IP_NUM[j]=parp->SrcIpAdd[j];
My_Arp[i].MAC_NUM[j]=parp->SrcMacAdd[j];
}
for(;j<6;j++)
{
My_Arp[i].MAC_NUM[j]=parp->SrcMacAdd[j];
}
My_Arp[i].TTL=100;
return 2;
}
}
while(1);
return 4; //arp表已经满了,调试
}
return 1;
}
/*
****************************************
*函数:arp_answer(uint8 *arp_rec_ptr)
*功能:
* 负责对arp表的更新和arp的应答
*
*
*参数:
* 接收到的arp数据报缓冲指针
*
****************************************
*/
INT8U Arp_Answer(INT8U *arp_rec_ptr)
{
_pkst TxArp;
INT8U i,j;
arp *parp;
parp=(arp *)arp_rec_ptr;
//是不是要解析本地的ip地址
if((parp->DestIpAdd[0])==My_Ip[0])
if((parp->DestIpAdd[1])==My_Ip[1])
if((parp->DestIpAdd[2])==My_Ip[2])
if((parp->DestIpAdd[3])==My_Ip[3]) //要解析本地ip
{
//将mac写上
for(i=0;i<6;i++)
{
parp->DestMacAdd[i]=parp->SrcMacAdd[i];
parp->SrcMacAdd[i]=My_Mac[i];
}
for(i=0;i<4;i++)
{
parp->DestIpAdd[i]=parp->SrcIpAdd[i];
parp->SrcIpAdd[i]=My_Ip[i];
}
parp->Opration=0x0200; //数据帧为应答帧
//修改一下缓冲结构,准备发送
TxArp.length=0x60;
TxArp.next=NULL;
TxArp.pdata=arp_rec_ptr;
Send_ethernet_Frame(&TxArp,parp->DestMacAdd,ARP_PACKED); //发送arp应答帧
//若是本网段还要刷新arp表
if(parp->DestIpAdd[0]==My_Ip[0])
if(parp->DestIpAdd[1]==My_Ip[1])
if(parp->DestIpAdd[2]==My_Ip[2])
{
for(i=0;i<MAX_ARP_NUM;i++)
{
if(parp->DestIpAdd[0]==My_Arp[i].IP_NUM[0])
if(parp->DestIpAdd[1]==My_Arp[i].IP_NUM[1])
if(parp->DestIpAdd[2]==My_Arp[i].IP_NUM[2])
if(parp->DestIpAdd[3]==My_Arp[i].IP_NUM[3]) //已经存在该arp表项
{
My_Arp[i].TTL=100;
return 0;
}
}
//没有找到该arp表项
for(i=0;i<MAX_ARP_NUM;i++)
{
if(My_Arp[i].TTL==0x00) //查找到一个空闲的arp表项
{
for(j=0;j<4;j++)
{
My_Arp[i].MAC_NUM[j]=parp->DestMacAdd[j];
My_Arp[i].IP_NUM[j]=parp->DestIpAdd[j];
}
My_Arp[i].MAC_NUM[4]=parp->DestMacAdd[4];
My_Arp[i].MAC_NUM[5]=parp->DestMacAdd[5];
My_Arp[i].TTL=100;
return 2;
}
}
while(1); //arp表已满,调试
return 4;
} //网管请求本机ip
return 3;
}
return 1; //不是本机的arp请求
}
/*
*****************************
*
*
* 测试main arp
*
*
*
*
*********************************
*/
static INT8U uper[4]={192,168,0,2};
INT8U back[6];
int Main(void)
{
eth_init();
eth_rx();
rtl8019_get_enetaddr(back);
while(1)
{
Arp_Request(uper);
eth_rx();
}
return 1;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -