📄 arp.c
字号:
#define ARP_GLOBALS
#include "config.h"
#include "../include/cfg_net.h"
typedef struct { /* arp报文的内容总长28字节*/
uint16 HardwareType; /*以太网为0x0001*/
uint16 ProtocalType; /*ip 为0X0800*/
uint8 HardwareLen; /*=0X06*/
uint8 ProtocalLen; /*=0X04*/
uint16 Operation; /*操作 0X0001为请求 0X0002为应答 */
/*0X0003为反向地址请求 0X0004为反向地址应答*/
uint8 SourceMacId[6]; /*源网卡地址*/
uint8 SourceIp[4]; /*源IP地址*/
uint8 DestMacId[6]; /*目的网卡地址*/
uint8 DestId[4]; /*目的IP地址*/
} arp ;
uint8 ARP_REP_MAC[6]={0XFF,0XFF,0XFF,0XFF,0XFF,0XFF};
uint8 Ping_Ip_Address[4];
uint8 Ping_IP_TTL;
//uint8 My_Ip_Address[4]=MY_IP;
//uint8 My_Gateway_Ip_Address[4]=MY_GATEWAY;
//uint8 MY_IP_MARK[4]=IP_MARK_SETTING;
//struct a_t ARP_TERM[MAX_ARP_TERM];
//===========================================================
/**********************************************************************
**函数原型: unsigned char Arp_Answer(unsigned char EX_RAM * ARP_REC_PTR)
**入口参数: * ARP_REC_PTR :接收到的ARP请求包的指针
**出口参数: unsigned char
**返 回 值: 0 :本子网内的ARP缓冲区已经有MAC
** 1 :目标IP不是本机不作回应
** 2 :本子网内的,但ARP缓冲区还没有MAC
** 3 :不是本子网的ARP请求
** 4 :ARP缓冲区已经满
**说 明: 对ARP请求报文的应答:填充本地物理地址,将ARP操作改为回答.
************************************************************************/
uint8 Arp_Answer(uint8 * ARP_REC_PTR,uint8 num)
{
struct _pkst TxdArp;
uint8 SEND_ARP_MAC[6];
uint8 i;
//如果目标IP地址是本机IP
if (((arp*)ARP_REC_PTR)->DestId[0]==NetPort[num].My_Ip[0])
if (((arp*)ARP_REC_PTR)->DestId[1]==NetPort[num].My_Ip[1])
if (((arp*)ARP_REC_PTR)->DestId[2]==NetPort[num].My_Ip[2])
if (((arp*)ARP_REC_PTR)->DestId[3]==NetPort[num].My_Ip[3])
{ //表示是要解析本地IP的请求
for(i=0;i<4;i++) //复制对方IP地址,填充源地址
{
SEND_ARP_MAC[i]=((arp*)ARP_REC_PTR)->SourceIp[i];
((arp*)ARP_REC_PTR)->SourceIp[i]=NetPort[num].My_Ip[i];
((arp*)ARP_REC_PTR)->DestId[i]=SEND_ARP_MAC[i];
}
for(i=0;i<6;i++)
{ //复制对方物理地址或网关地址
SEND_ARP_MAC[i]=((arp*)ARP_REC_PTR)->SourceMacId[i];
((arp*)ARP_REC_PTR)->SourceMacId[i]=NetPort[num].My_Mac[i];
((arp*)ARP_REC_PTR)->DestMacId[i]=SEND_ARP_MAC[i];
}
#ifdef Big_End
((arp*)ARP_REC_PTR)->Operation=0x0002; //表明数据帧为ARP应答
#endif
#ifdef Little_End
((arp*)ARP_REC_PTR)->Operation=0x0200; //表明数据帧为ARP应答
#endif
TxdArp.STPTR=NULL;
TxdArp.length=0x60;
TxdArp.DAPTR=ARP_REC_PTR;
Send_ethernet_Frame(&TxdArp,SEND_ARP_MAC,ARP_PACKED,num);//发送ARP应答帧
//如果发送方属于本网段
if((((arp*)ARP_REC_PTR)->SourceIp[0]&NetPort[num].My_Ip_Mark[0])==(NetPort[num].My_Ip[0]&NetPort[num].My_Ip_Mark[0]))
if((((arp*)ARP_REC_PTR)->SourceIp[1]&NetPort[num].My_Ip_Mark[1])==(NetPort[num].My_Ip[1]&NetPort[num].My_Ip_Mark[1]))
if((((arp*)ARP_REC_PTR)->SourceIp[2]&NetPort[num].My_Ip_Mark[2])==(NetPort[num].My_Ip[2]&NetPort[num].My_Ip_Mark[2]))
if((((arp*)ARP_REC_PTR)->SourceIp[3]&NetPort[num].My_Ip_Mark[3])==(NetPort[num].My_Ip[3]&NetPort[num].My_Ip_Mark[3]))
{
//查找有否属于该IP的对应MAC表
for(i=0;i<MAX_ARP_TERM;i++)
{
if(NetPort[num].ARP_TERM[i].IP_NUM[2]==((arp*)ARP_REC_PTR)->SourceIp[2])
if(NetPort[num].ARP_TERM[i].IP_NUM[3]==((arp*)ARP_REC_PTR)->SourceIp[3])
if(NetPort[num].ARP_TERM[i].TTL>0)
{//有则刷新
NetPort[num].ARP_TERM[i].TTL=100;
return(0);
}
}
//查找有否空的MAC表项
for(i=0;i<MAX_ARP_TERM;i++)
{
if(NetPort[num].ARP_TERM[i].TTL==0)
{//有则保存
NetPort[num].ARP_TERM[i].IP_NUM[0]=((arp*)ARP_REC_PTR)->SourceIp[0];
NetPort[num].ARP_TERM[i].IP_NUM[1]=((arp*)ARP_REC_PTR)->SourceIp[1];
NetPort[num].ARP_TERM[i].IP_NUM[2]=((arp*)ARP_REC_PTR)->SourceIp[2];
NetPort[num].ARP_TERM[i].IP_NUM[3]=((arp*)ARP_REC_PTR)->SourceIp[3];
NetPort[num].ARP_TERM[i].MAC_NUM[0]=((arp*)ARP_REC_PTR)->SourceMacId[0];
NetPort[num].ARP_TERM[i].MAC_NUM[1]=((arp*)ARP_REC_PTR)->SourceMacId[1];
NetPort[num].ARP_TERM[i].MAC_NUM[2]=((arp*)ARP_REC_PTR)->SourceMacId[2];
NetPort[num].ARP_TERM[i].MAC_NUM[3]=((arp*)ARP_REC_PTR)->SourceMacId[3];
NetPort[num].ARP_TERM[i].MAC_NUM[4]=((arp*)ARP_REC_PTR)->SourceMacId[4];
NetPort[num].ARP_TERM[i].MAC_NUM[5]=((arp*)ARP_REC_PTR)->SourceMacId[5];
NetPort[num].ARP_TERM[i].TTL=100;
return(2);
}
}//FOR
//MAC表已经满
return(4);
}//IF ARP
//不属于同一网段的
return (3);
}
//目标IP不是本机
return (1);
}
uint8 REC_ARP_REQ(uint8 * ARP_REC_REQ_PTR,uint8 num)
{
uint8 i;
//======================================================================
if(((arp*)ARP_REC_REQ_PTR)->SourceIp[0]==NetPort[num].My_Gateway[0])
if(((arp*)ARP_REC_REQ_PTR)->SourceIp[1]==NetPort[num].My_Gateway[1])
if(((arp*)ARP_REC_REQ_PTR)->SourceIp[2]==NetPort[num].My_Gateway[2])
if(((arp*)ARP_REC_REQ_PTR)->SourceIp[3]==NetPort[num].My_Gateway[3])
{ //表示是网关对ARP请求的回答.
for (i=0;i<6;i++)
{
NetPort[num].My_Gateway_Mac[i]=((arp*)ARP_REC_REQ_PTR)->SourceMacId[i];
}
NetPort[num].Gateway_IP_TTL=100; //表示网关地址已得到解析
//return(3);
}
//如果发送方属于本网段
if((((arp*)ARP_REC_REQ_PTR)->SourceIp[0]&NetPort[num].My_Ip_Mark[0])==(NetPort[num].My_Ip[0]&NetPort[num].My_Ip_Mark[0]))
if((((arp*)ARP_REC_REQ_PTR)->SourceIp[1]&NetPort[num].My_Ip_Mark[1])==(NetPort[num].My_Ip[1]&NetPort[num].My_Ip_Mark[1]))
if((((arp*)ARP_REC_REQ_PTR)->SourceIp[2]&NetPort[num].My_Ip_Mark[2])==(NetPort[num].My_Ip[2]&NetPort[num].My_Ip_Mark[2]))
if((((arp*)ARP_REC_REQ_PTR)->SourceIp[3]&NetPort[num].My_Ip_Mark[3])==(NetPort[num].My_Ip[3]&NetPort[num].My_Ip_Mark[3]))
{//查找有否属于该IP的对应MAC表
for(i=0;i<MAX_ARP_TERM;i++)
{
if(NetPort[num].ARP_TERM[i].IP_NUM[2]==((arp*)ARP_REC_REQ_PTR)->SourceIp[2])
if(NetPort[num].ARP_TERM[i].IP_NUM[3]==((arp*)ARP_REC_REQ_PTR)->SourceIp[3])
if(NetPort[num].ARP_TERM[i].TTL>0)
{//有则刷新
NetPort[num].ARP_TERM[i].TTL=100;
return(0);
}
}
//查找有否空的MAC表项
for(i=0;i<MAX_ARP_TERM;i++)
{
if(NetPort[num].ARP_TERM[i].TTL==0)
{//有则保存
NetPort[num].ARP_TERM[i].IP_NUM[0]=((arp*)ARP_REC_REQ_PTR)->SourceIp[0];
NetPort[num].ARP_TERM[i].IP_NUM[1]=((arp*)ARP_REC_REQ_PTR)->SourceIp[1];
NetPort[num].ARP_TERM[i].IP_NUM[2]=((arp*)ARP_REC_REQ_PTR)->SourceIp[2];
NetPort[num].ARP_TERM[i].IP_NUM[3]=((arp*)ARP_REC_REQ_PTR)->SourceIp[3];
NetPort[num].ARP_TERM[i].MAC_NUM[0]=((arp*)ARP_REC_REQ_PTR)->SourceMacId[0];
NetPort[num].ARP_TERM[i].MAC_NUM[1]=((arp*)ARP_REC_REQ_PTR)->SourceMacId[1];
NetPort[num].ARP_TERM[i].MAC_NUM[2]=((arp*)ARP_REC_REQ_PTR)->SourceMacId[2];
NetPort[num].ARP_TERM[i].MAC_NUM[3]=((arp*)ARP_REC_REQ_PTR)->SourceMacId[3];
NetPort[num].ARP_TERM[i].MAC_NUM[4]=((arp*)ARP_REC_REQ_PTR)->SourceMacId[4];
NetPort[num].ARP_TERM[i].MAC_NUM[5]=((arp*)ARP_REC_REQ_PTR)->SourceMacId[5];
NetPort[num].ARP_TERM[i].TTL=100;
return(2);
}
}
//MAC表已经满
return(4);
}
//对方IP即不是本网段也不是GATEWAY
return(1);
}
//===========================================================================
//=======================================================================
/**********************************************************************
**函数原型: void PROCESS_ARP_REC(unsigned char EX_RAM * ARP_PTR)
**入口参数: * ARP_PTR :接收到的ARP包的指针
**出口参数: 无
**返 回 值: 无
**说 明: 对ARP包进行分类处理
************************************************************************/
void PROCESS_ARP_REC(uint8 * ARP_PTR,uint8 num)
{
// EX_RAM PKST ARP_PACKED;
#ifdef Big_End
if(((arp*)ARP_PTR)->Operation==0X0001)
#endif
#ifdef Little_End
if(((arp*)ARP_PTR)->Operation==0X0100)
#endif
{
Arp_Answer(ARP_PTR,num);
}
#ifdef Big_End
else if(((arp*)ARP_PTR)->Operation==0X0002)
#endif
#ifdef Little_End
else if(((arp*)ARP_PTR)->Operation==0X0200)
#endif
{
REC_ARP_REQ(ARP_PTR,num);
}
//可添加REARP操作。
}
/**********************************************************************
**函数原型:
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -