📄 eth.c
字号:
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 + -