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

📄 arp.c

📁 rtl8019的程序
💻 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 + -