📄 eth.c
字号:
void reconstruct_ping(unsigned char table_index)
{
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_table[table_index].ip.words[0];
txdnet.ipframe.destip[1]=ping_table[table_index].ip.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();
}
//------------------------------------------------------------------------
//函数功能:定时操作,放在1秒循环任务中
//
//入参: 无
//
//返回值: 无
//
//
//作者:
//
//注意: 用于对PING_TABLE进行操作,该函数是处理PING的最重要函数
//
//
//注释: Mingtree
//日期: 2004-10-28
//------------------------------------------------------------------------
void PingCycle() //定时操作,放在1秒循环任务中
{
unsigned char i;
//对PING_TABLE表进行扫
for(i=0;i<MaxLenPingBuf;i++)
{
switch(ping_table[i].status)
{
case 0:
//空闲,直接返回
break;
case 1: //已发出但无应答(过了1s还未应答),输出超时
//TODO
//在这里添加串口发送代码,先上位机显示主机不可达
PrintUnreach();
break;
case 2: //发出且应答.注意,如果收到回显应答,则在PING_ECHO里进行处理,对状态进行修改
ping_table[i].times=ping_table[i].times-1;
if(0==ping_table[i].times)
{
ping_table[i].status=0;
break;
}
case 4: ////第一次准备发(用于同步1秒时钟)
//查ARP缓存
if(findmacadr(ping_table[i].ip,&ping_ethernet_address))
{
//因为发送缓冲区的内容已经发生改变,因此重新构造PING包
reconstruct_ping(i);
//填写发送包的MAC地址
ping_table[i].pack->etherframe.uDestID[0]=ping_ethernet_address.words[0];
ping_table[i].pack->etherframe.uDestID[1]=ping_ethernet_address.words[1];
ping_table[i].pack->etherframe.uDestID[2]=ping_ethernet_address.words[2];
//进行发送
send_packet(ping_table[i].pack,74);
//改变状态
ping_table[i].status=1;
}
else
{
//ARP表里没有对应项,发送ARP请求
arp_request(ping_table[i].ip);
//改变状态
ping_table[i].status=3;
}
break;
case 3: //等待ARP
//查ARP缓存
if(findmacadr(ping_table[i].ip,&ping_ethernet_address))
{
//因为发送缓冲区的内容已经发生改变,因此重新构造PING包
reconstruct_ping(i);
//填写发送包的MAC地址
ping_table[i].pack->etherframe.uDestID[0]=ping_ethernet_address.words[0];
ping_table[i].pack->etherframe.uDestID[1]=ping_ethernet_address.words[1];
ping_table[i].pack->etherframe.uDestID[2]=ping_ethernet_address.words[2];
//进行发送
send_packet(ping_table[i].pack,74);
}
//已经发出ARP,但是没发回,改变状态
ping_table[i].status=1;
break;
default:
ping_table[i].status=0;
}
}
}
//------------------------------------------------------------------------
//函数功能?
//
//入参: 无
//
//
//
//
//作者:
//
//注意:
//
//
//注释: Mingtree
//日期: 2004-10-28
//------------------------------------------------------------------------
bit query_8019()
{
char bnry,curr;
page(0);
bnry=reg03; //bnry page have read 读页指针
page(1);
curr=reg07; //curr writepoint 8019写页指针
page(0);
if ((curr==0)) return 0;
bnry=bnry++;
if (bnry>0x7f) bnry=0x4c;
if (bnry!=curr) //此时表示有新的数据包在缓冲区里
return 1;
reg0b=0x00; reg0a=0x00; reg00=0x22;//complete dma page 0
}
unsigned int checksum(unsigned int xdata *check,unsigned int length)//计算校验和
{
unsigned long sum=0;
unsigned int i;
for (i=0;i<(length)/2;i++)
sum+=*check++;
if(length&0x01)//表示长度为单数
sum=sum+((*check)&0xff00);
sum=(sum&0xffff)+((sum>>16)&0xffff);//高16位和低16位相加
if(sum&0xffff0000)//表示有进位
sum++;
return ( (unsigned int)(~((sum)&0xffff)) );
}
bit verifyipheadcrc(union netcard xdata *pRxdnet)//对ip头进行校验,错误返回0,正确返回1
{
unsigned int crc;
crc=checksum(&(pRxdnet->ippacket.ippacket[0]),(pRxdnet->ipframe.verandihl&0x0f)*4);
if(crc==0) return (1);
return(0);
}
//------------------------------------------------------------------------
//函数功能:主循环
//
//入参: 无
//
//
//
//
//作者:
//
//注意:
//
//
//注释: Mingtree
//日期: 2004-11-10
//------------------------------------------------------------------------
void maincycle(void)//主循环
{
if(recv_packet(&rxdnet)==1)
{ //PrintStr("Good packet!");
temp_ip_address.words[0]=rxdnet.ipframe.destip[0];
temp_ip_address.words[1]=rxdnet.ipframe.destip[1];
if(rxdnet.etherframe.protocal==0x0806)
{//表示收到一个arp请求包
if(rxdnet.arpframe.operation==0x0001)
arp_answer();//ARP request,处理arp数据包
if(rxdnet.arpframe.operation==0x0002)
{
arp_process();//ARP answer
//tcp保活测试
TCP_ATYARP();
}
}
else
if((rxdnet.etherframe.protocal==0x0800)&&((rxdnet.ipframe.verandihl&0xf0)==0x40)&&(temp_ip_address.dwords==my_ip_address.dwords))
{
if(verifyipheadcrc(&rxdnet))
{//表示收到一个ip包,仅处理ip v4
switch(rxdnet.ipframe.protocal)
{
case 1://表示为icmp协议
if(rxdnet.icmpframe.type==8) //是一个ping的请求包
ping_answer();
else if(rxdnet.icmpframe.type==0)
ping_echo(); //是一个ping的应答包
break;
case 6: //表示是tcp协议
// process_tcp();
tcp_rcve(&rxdnet);
break;
case 0x11: //表示是udp协议
udp_rcve(&rxdnet);
break;
default:;
}
}
}
}
}
//******************************************************
//函数功能:读网关配置信息
//参数:
//
//说明:
//作者: Mingtree
//日期: 2005-11-03
//******************************************************
void ReadGateway()
{
unsigned char i;
//网关IP
for(i=0;i<4;i++)
{
addr0=RLDDR;
addr1=GATEIP+i;
x5045ReadData();
gateway_ip_address.bytes[i]=WriteBuf;
}
//子网掩码
mask_ip_address.bytes[0] = 255;
mask_ip_address.bytes[1] = 255;
mask_ip_address.bytes[2] = 255;
mask_ip_address.bytes[3] = 0;
}
//******************************************************
//函数功能:读本地IP
//参数:
//
//说明:
//作者: Mingtree
//日期: 2004-09-12
//******************************************************
void ReadLIP()
{
unsigned char i;
for(i=0;i<4;i++)
{
addr0=RLDDR;
addr1=LIPADDR+i;
x5045ReadData();
my_ip_address.bytes[i]=WriteBuf;
}
}
//******************************************************
//函数功能:读本地MAC
//参数:
//
//说明:
//作者: Mingtree
//日期: 2004-09-12
//******************************************************
void ReadMAC()
{
unsigned char i;
for(i=0;i<6;i++)
{
addr0=RLDDR;
addr1=MACADDR+i;
x5045ReadData();
my_ethernet_address.bytes[i]=WriteBuf;
}
}
void PingDisp()
{
unsigned char xdata Echo[255]={'R','e','p','l','y',' ','f','r','o','m'};
unsigned char xdata IP[16];
unsigned char i;
HEXToIPadr(IP,&ping_ip_address);
//16为255.255.255.255整个字符的长度,包括“.”
for(i=0;i<16;i++)
Echo[10+i]=IP[i];
PrintStr(Echo);
}
void HEXToIPadr(unsigned char xdata *Str,union IP_address xdata *ip)
{
unsigned char i;
unsigned char x,y;
for(i=0;i<4;i++){
x=ip->bytes[i];
if(x>99){
y=x/100;*Str++=y+'0';
x=x-100*y;y=x/10;*Str++=y+'0';
x=x-10*y;*Str++=x+'0';
if(i==3) *Str++='\0';
else *Str++='.';
}
else if(x>9){
y=x/10;*Str++=y+'0';
x=x-10*y;*Str++=x+'0';
if(i==3) *Str++='\0';
else *Str++='.';
}
else{
*Str++=x+'0';
if(i==3) *Str++='\0';
else *Str++='.';
}
}
}
void PrintUnreach()//显示字符串
{
unsigned char xdata Host[255]={'H','o','s','t',' '};
unsigned char xdata IP[16];
unsigned char xdata Unreach[13]={'U','n','r','e','a','c','h','a','b','l','e','!','\0'};
unsigned char i,j;
HEXToIPadr(IP,&ping_ip_address);
//16为255.255.255.255整个字符的长度,包括“.”
for(i=0;i<16;i++)
Host[5+i]=IP[i];
//定位'\0'
for(i=0;i<16;i++)
{
if(0x00==IP[i])
break;
}
if(i<16)
j=i;
else
j=15;
for(i=0;i<13;i++)
Host[5+j+i]=Unreach[i];
PrintStr(Host);
}
/*
void Test8019()
{
unsigned char i,temp=0;
reg09=0x40; //txdwrite highaddress
reg08=0x00; //read page address low
reg0b=00; //read count high
reg0a=16; //read count low;
reg00=0x12;
for(i=0;i<16;i++)
{
reg10=temp;
temp++;
}
reg0b=0x00; //read count high 中止DMA操作
reg0a=0x00; //read count low;
reg00=0x22; //complete dma page 0
//读
reg09=0x40; //read page address high
reg08=0x00; //read page address low
reg0b=0x00; //read count high
reg0a=16; //read count low;
reg00=0x0A; //read dma
for(i=0;i<16;i++)
{
temp=reg10;
PrintByte(temp);
}
// 以下3句为中止dma的操作,可以不要
reg0b=0x00; //read count high 中止DMA操作
reg0a=0x00; //read count low;
reg00=0x22; //complete dma page 0
} */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -