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

📄 arp.c

📁 本程序是一个RS232转网口的。是一个透明传输的模块
💻 C
字号:
/*
*****************************************************************************************************
*
*  File name: arp.c
*****************************************************************************************************
*/
#include "..\head\includes.h"


#define MaxLenARPtable	10			                   //ARP表长度

xdata union arp_table_type arp_tab[MaxLenARPtable];	   //ARP表,存在外部RAM区里
unsigned char index=0;								   //ARP table 循环加入点

/*
*****************************************************************************************************
*FUNC: 向指定的IP地址发送一个ARP请求
*NOTE: 
*****************************************************************************************************
*/
void ArpRequest(union IP_address ip_address)//ARP请求
{
	unsigned char i;

	txdnet.etherframe.protocal=0x0806;                                   //arp protocal

	for (i=0; i<3; i++) {                                                //复制对方网卡地址或网关地址
   		txdnet.etherframe.uDestID[i]    = 0xffff;                        //IP广播地址
		txdnet.etherframe.uSourceID[i]  = my_ethernet_address.words[i];  //指定以太网数据包首部中的源MAC地址
		txdnet.arpframe.sourcenodeid[i] = my_ethernet_address.words[i];
		txdnet.arpframe.destnodeid[i]   = 0x0000;                        //此时目的MAC未知,填0
    }

	for (i=0;i<2;i++) {
		txdnet.arpframe.sourceip[i] = my_ip_address.words[i];   //我的IP
	}
    txdnet.arpframe.destip[0]=ip_address.words[0];              //目标IP
    txdnet.arpframe.destip[1]=ip_address.words[1];
	txdnet.arpframe.harewaretype=0x0001;                        //1即表示以太网地址
	txdnet.arpframe.protocaltype=0x0800;
	txdnet.arpframe.halength=0x06;
	txdnet.arpframe.palength=0x04;
 	txdnet.arpframe.operation=0x0001;                           //ARP请求 
	for(i=0x2E; i<(0x2E+18); i++) {                             //不足60补0                       
		txdnet.bytes.bytebuf[i]=0x00;
	}
	send_packet(&txdnet,60);
}

/*
*****************************************************************************************************
*FUNC: 收到一个ARP应答后,对ARP表进行处理
*NOTE: void ArpRequest(union IP_address ip_address)//ARP请求的应答处理
*****************************************************************************************************
*/
void ArpEcho(void)                        //ARP应答处理
{
	unsigned char i,j;
	unsigned char processed=FALSE;

	//其中的状态字段表示该ARP记录是否已经被占用.1表示占用,0表示未占用
	//当状态为1时,需要对表进行搜索,对表进行更新.显然,当收到一个新的ARP
	//包后,首先需要处理的是该ARP记录是否在表中,如果是,则进行更新;否则添
	//加该记录

	//对表进行搜索,确定是否需要更新
	for (i=0; i<MaxLenARPtable; i++) {
		if (arp_tab[i].arp.status == 1) {
			if ((arp_tab[i].arp.ip_address.words[0] == rxdnet.arpframe.sourceip[0])
			    && (arp_tab[i].arp.ip_address.words[1]==rxdnet.arpframe.sourceip[1])) //判断该记录是否已存在
			{
					arp_tab[i].arp.ttl = 0x80;                                        //已存在,就更新它
					for (j=0; j<2; j++) {
						arp_tab[i].arp.ip_address.words[j]=rxdnet.arpframe.sourceip[j];
					}
					for (j=0; j<3; j++) {
						arp_tab[i].arp.ethernet_address.words[j]=rxdnet.arpframe.sourcenodeid[j];
					}
					processed=TRUE;                                                   //已处理更新标志
					break;
			}
		}
	}

	if (!processed) {                               //未处理	
		for (i=0; i<MaxLenARPtable; i++) {          //添加一条记录
			if (arp_tab[i].arp.status == 0) {
				arp_tab[i].arp.status = 1;
				arp_tab[i].arp.ttl = 0x80;
				for (j=0; j<2; j++) {
					arp_tab[i].arp.ip_address.words[j]=rxdnet.arpframe.sourceip[j];
				}
				for(j=0; j<3; j++) {
					arp_tab[i].arp.ethernet_address.words[j]=rxdnet.arpframe.sourcenodeid[j];
				}
				processed=TRUE;                     //已添加标志
				break;
			}
		}
	}

	if (!processed) {                               //未更新,未添加,说明表满
		arp_tab[index].arp.status = 1;              //表满处理.其中index为全局变量,循环更新ARP表
		arp_tab[index].arp.ttl = 0x80;
		for (j=0; j<2; j++) {
			arp_tab[index].arp.ip_address.words[j]=rxdnet.arpframe.sourceip[j];
		}
		for (j=0; j<3; j++) {
			arp_tab[index].arp.ethernet_address.words[j]=rxdnet.arpframe.sourcenodeid[j];
		}
		if (++index == MaxLenARPtable) {
	        index = 0;
		}
	}

	if ((arpwait.wait_arp == TRUE) && (arpwait.ipaddr.words[0] == rxdnet.arpframe.sourceip[0]) 
	   && (arpwait.ipaddr.words[1] == rxdnet.arpframe.sourceip[1])) {  //有数据在等待ARP,发送
   		arpwait.wait_arp = FALSE;
		ip_send(arpwait.buf, arpwait.ipaddr, arpwait.proto_id, arpwait.len);
	}
}

/*
*****************************************************************************************************
*FUNC: 对ARP请求进行应答
*NOTE: 
*****************************************************************************************************
*/
void ArpAnswer(void)
{
	unsigned char i;

	if (rxdnet.arpframe.destip[0]==my_ip_address.words[0])
	if (rxdnet.arpframe.destip[1]==my_ip_address.words[1]) {              //表示是向我这个ip地址的请求
        for (i=16; i<64; i++) {                                           //复制arp到发送缓冲区
    		txdnet.bytes.bytebuf[i]=rxdnet.bytes.bytebuf[i];
		}
    	for (i=0; i<3; i++) {                                             //复制对方网卡地址或网关地址
	        txdnet.etherframe.uDestID[i] = rxdnet.etherframe.uSourceID[i];
	        txdnet.etherframe.uSourceID[i]=my_ethernet_address.words[i];  //指定以太网数据包首部中的源MAC地址
	        txdnet.arpframe.sourcenodeid[i]=my_ethernet_address.words[i];
	        txdnet.arpframe.destnodeid[i]=rxdnet.arpframe.sourcenodeid[i];
    	}

	    for (i=0; i<2; i++) {
		    txdnet.arpframe.destip[i]   = rxdnet.arpframe.sourceip[i];
	        txdnet.arpframe.sourceip[i] = rxdnet.arpframe.destip[i];
	    }

		txdnet.arpframe.operation=0x0002;                                 //ARP响应代码
	    send_packet(&txdnet,60);
	}
}
/*
*****************************************************************************************************
*FUNC: 初始化ARP缓存
*NOTE: 
*****************************************************************************************************
*/
void InitArpTable(void)
{
	unsigned char i,j;

	for (i=0; i<MaxLenARPtable; i++) {
		arp_tab[i].arp.status=0;
		arp_tab[i].arp.ttl=0;
		for (j=0; j<4; j++) {
			arp_tab[i].arp.ip_address.bytes[j]=0;
		}
		for (j=0; j<6; j++) {
			arp_tab[i].arp.ethernet_address.bytes[j]=0;
		}
	}
}


/*
*****************************************************************************************************
*FUNC: 更新ARP缓存
*NOTE: 每1s调用一次
*****************************************************************************************************
*/
void UpdateArpTab()
{
	unsigned char i;

	for (i=0; i<MaxLenARPtable; i++) {
		if (arp_tab[i].arp.status == 1) {
		    if (arp_tab[i].arp.ttl > 0) {   //生存时间
                arp_tab[i].arp.ttl--;
			} else {
                arp_tab[i].arp.status=0;
			}
        }
	}
}


/*
*****************************************************************************************************
*FUNC:在ARP缓存中查找指定IP/MAC映射对
*NOTE: 入参:	指定的IP地址,返回MAC地址的指针
      返回值:	bit类型.如果找到,则返回1;找不到则返回0.
*****************************************************************************************************
*/
bit FindMac(union IP_address ip,union Ethernet_address xdata *macadr)
{
	unsigned char i,j;

	for (i=0; i<MaxLenARPtable; i++){
		if (arp_tab[i].arp.status == 1) {
			if(arp_tab[i].arp.ip_address.dwords == ip.dwords){
				for(j=0; j<3; j++) {
					macadr->words[j]=arp_tab[i].arp.ethernet_address.words[j];
				}
				return 1;
		    }
		}
	}
	return 0;
}

⌨️ 快捷键说明

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