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

📄 eth.c

📁 基于51单片机和RTL8019以太网控制器的嵌入式以太网控制程序。
💻 C
📖 第 1 页 / 共 3 页
字号:
    	   for(i=0;i<3;i++)
	   {//复制对方网卡地址或网关地址
	        txdnet.etherframe.uDestID[i]=rxdnet.etherframe.uSourceID[i];
	        //指定以太网数据包首部中的源MAC地址
	        txdnet.etherframe.uSourceID[i]=my_ethernet_address.words[i];
	        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;//响应代码

	   send_packet(&txdnet,60);
	}
}
//------------------------------------------------------------------------
//函数功能:收到一个ARP应答后,对ARP表进行处理
//
//入参:	无
//
//返回值:	无
//
//作者:
//
//注释:	Mingtree
//日期:	2004-10-06
//------------------------------------------------------------------------
void arp_process()//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])
				if(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)
	{
		//表满处理.其中index为全局变量
		arp_tab[index].arp.status=1;	//write arp package to some location.
		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];
		index++;
		if(index==MaxLenARPtable) index=0;
	}
	if ((arpwait.wait_arp) && (arpwait.ipaddr.words[0]==rxdnet.arpframe.sourceip[0])&& (arpwait.ipaddr.words[1]==rxdnet.arpframe.sourceip[1]))
   	{
   		arpwait.wait_arp = FALSE;
		ip_send(arpwait.buf, arpwait.ipaddr, arpwait.proto_id, arpwait.len);
	}
}
//------------------------------------------------------------------------
//函数功能://初始化ARP缓存
//
//入参:	无
//
//返回值:	无
//
//作者:
//
//注释:	Mingtree
//日期:	2004-10-28
//------------------------------------------------------------------------
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;
	}
}
//------------------------------------------------------------------------
//函数功能:更新ARP缓存
//
//入参:	无
//
//返回值:	无
//
//注意:	每1s调用一次
//
//作者:
//
//注释:	Mingtree
//日期:	2004-11-03
//------------------------------------------------------------------------
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.status=0;
			else arp_tab[i].arp.ttl--;
	}
}
//------------------------------------------------------------------------
//函数功能:在ARP缓存中查找指定IP/MAC映射对
//
//入参:	指定的IP地址,返回MAC地址的指针
//
//返回值:	bit类型.如果找到,则返回1;找不到则返回0.
//
//作者:
//
//注释:	Mingtree
//日期:	2004-10-27
//------------------------------------------------------------------------
bit findmacadr(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;
}
//------------------------------------------------------------------------
//函数功能:初始化PING表
//
//入参:	无
//
//返回值:	无
//
//作者:
//
//注释:	Mingtree
//日期:	2004-10-28
//------------------------------------------------------------------------
void InitPingTable(void)
{
	unsigned char i;
	for(i=0;i<MaxLenPingBuf;i++)
		ping_table[i].status=0;
}
//------------------------------------------------------------------------
//函数功能://生成IP包头CRC校验
//
//入参:	无
//
//返回值:	CRC校验值
//
//
//作者:
//
//注意:
//
//
//注释:	Mingtree
//日期:	2004-10-28
//------------------------------------------------------------------------
unsigned int createipheadcrc(union netcard xdata *pTxdnet)
{
	unsigned int crc;
	crc = checksum(pTxdnet->words.wordbuf + 9, 20);
	return crc;
}
//------------------------------------------------------------------------
//函数功能:生成ICMP包头CRC校验
//
//入参:	无
//
//返回值:	CRC校验值
//
//
//作者:
//
//注意:
//
//
//注释:	Mingtree
//日期:	2004-10-28
//------------------------------------------------------------------------
unsigned int createicmpcrc()//生成ICMP包CRC校验
{
	unsigned char i;
	union w crctemp;

	crctemp.dwords=0;
	for(i=19;i<39;i++)
		crctemp.dwords=crctemp.dwords+txdnet.words.wordbuf[i];
	while(crctemp.words.high>0)
    	crctemp.dwords=(unsigned long)(crctemp.words.high+crctemp.words.low);
	crctemp.words.low=0xffff-crctemp.words.low;
	return(crctemp.words.low);
}

//------------------------------------------------------------------------
//函数功能:PING请求,实际上,该函数只是在缓冲区里构造一个ICMP包,然后在PING_TABLE里登记该PING
//			记录,该ICMP包的发送是在PING_CYCLE里实现的
//
//入参:	ping_ip_address,PING服务器IP地址
//
//返回值:	无
//
//
//作者:
//
//注意:
//
//
//注释:	Mingtree
//日期:	2004-10-06
//------------------------------------------------------------------------
void ping_request()
{
	unsigned char  i;
//	txdnet.etherframe.destnodeid[0]=ping_ethernet_address.words[0];
//	txdnet.etherframe.destnodeid[1]=ping_ethernet_address.words[1];
//	txdnet.etherframe.destnodeid[2]=ping_ethernet_address.words[2];
	txdnet.etherframe.protocal=0x0800;
	txdnet.ipframe.verandihl=0x45;
	txdnet.ipframe.typeofserver=0x00;
	txdnet.ipframe.totallength=60;
    txdnet.ipframe.ttl=0x80;
	txdnet.ipframe.frameindex=frameindex;
	frameindex++;
	txdnet.ipframe.segment=0x0000;
	txdnet.ipframe.protocal=0x0001;//icmp
    txdnet.ipframe.crc=0;
    txdnet.ipframe.destip[0]=ping_ip_address.words[0];
    txdnet.ipframe.destip[1]=ping_ip_address.words[1];
    txdnet.ipframe.sourceip[0]=my_ip_address.words[0];
    txdnet.ipframe.sourceip[1]=my_ip_address.words[1];
    txdnet.ipframe.crc=createipheadcrc(&txdnet);
    txdnet.icmpframe.type=0x08;// is icmp request;
	txdnet.icmpframe.option=0x00;		//该句由Mingtree加
    txdnet.icmpframe.crc=0;
	txdnet.icmpframe.id=0x0300;
	txdnet.icmpframe.seq=frameindex;
    txdnet.icmpframe.crc=createicmpcrc();
	//将该包登记入ping表里
	for(i=0;i<MaxLenPingBuf;i++)
	{
        if(ping_table[i].status==0)
		{
            ping_table[i].times=0x4;						 //测试8次
            ping_table[i].ip.dwords=ping_ip_address.dwords;	 //ping命令传入的IP地址;
            ping_table[i].pack=&txdnet;						 //发送缓冲区地址
            ping_table[i].status=4;							 //第一次准备发(用于同步1秒时钟)
            break;
        }
    }
}
//------------------------------------------------------------------------
//函数功能:PING应答
//
//入参:	无
//
//返回值:	无
//
//
//作者:
//
//注意:
//
//
//注释:	Mingtree
//日期:	2004-10-13
//------------------------------------------------------------------------
void ping_answer()//????????????????????????//PING应答
{
	unsigned char i;

	if(rxdnet.icmpframe.type==0x08)
	{//表示是ping请求
		//将数据复制到发送缓冲区
		//从16开始的原因:1字节的接收状态,1字节下一页指针,2字节以太网包长度,
		//12字节MAC地址,加起来为16字节.接着的信息为包类型,可以拷贝
    	for (i=16;i<rxdnet.etherframe.uLength;i++)
 	    	txdnet.bytes.bytebuf[i]=rxdnet.bytes.bytebuf[i];
    	txdnet.etherframe.uDestID[0]=rxdnet.etherframe.uSourceID[0];
	    txdnet.etherframe.uDestID[1]=rxdnet.etherframe.uSourceID[1];
    	txdnet.etherframe.uDestID[2]=rxdnet.etherframe.uSourceID[2];

		txdnet.etherframe.uSourceID[0]=rxdnet.etherframe.uDestID[0];
	    txdnet.etherframe.uSourceID[1]=rxdnet.etherframe.uDestID[1];
    	txdnet.etherframe.uSourceID[2]=rxdnet.etherframe.uDestID[2];

	    txdnet.ipframe.ttl=txdnet.ipframe.ttl-1;
    	txdnet.ipframe.crc=0;
	    txdnet.ipframe.destip[0]=rxdnet.ipframe.sourceip[0];
    	txdnet.ipframe.destip[1]=rxdnet.ipframe.sourceip[1];
	    txdnet.ipframe.sourceip[0]=my_ip_address.words[0];
    	txdnet.ipframe.sourceip[1]=my_ip_address.words[1];
	    txdnet.ipframe.crc=createipheadcrc(&txdnet);
    	txdnet.icmpframe.type=0x00;// is icmp answer;
		txdnet.icmpframe.option=0x00;
	    txdnet.icmpframe.crc=0;

		txdnet.icmpframe.crc=createicmpcrc();
    	send_packet(&txdnet,rxdnet.etherframe.uLength);
	}
}
//------------------------------------------------------------------------
//函数功能:PING回显,该函数在收到包,判断包为PING回显后调用,对PING表里的状态进行改变
//
//入参:	无
//
//返回值:	无
//
//
//作者:
//
//注意:
//
//
//注释:	Mingtree
//日期:	2004-10-28
//------------------------------------------------------------------------
void ping_echo()//PING应答收到后回显
{
	unsigned char i;
	temp_ip_address.words[0]=rxdnet.ipframe.sourceip[0];
	temp_ip_address.words[1]=rxdnet.ipframe.sourceip[1];
	for(i=0;i<MaxLenPingBuf;i++)
	{
		if((ping_table[i].status==1)&&(ping_table[i].ip.dwords==temp_ip_address.dwords))
		{
			ping_table[i].status=2;
			break;
		}
	}
	//TODO,在这里添加代码,显示收到PING包
//	P10=1;
//	Delay1ms(255);
//	P10=0;
	PingDisp();
}
//------------------------------------------------------------------------
//函数功能:重新建立PING数据包
//
//入参:	需要重构的表索引
//
//返回值:	无
//
//
//作者:
//
//注意:	在进行ping时,如果要先发送一个ARP数据包,则会对由ping_requeset()函数形成的
//			PING包进行破坏,该函数的功能就是重新构造PING包。构造该包的信息在PING_TABLE里
//
//
//注释:	Mingtree
//日期:	2004-10-28
//------------------------------------------------------------------------

⌨️ 快捷键说明

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