📄 protocol.c
字号:
{
case 0x0806:
if(rxdnet.arpframe.operation==0x0001){arp_answer();}/*ARP request*/
else if( rxdnet.arpframe.operation==0x0002){arp_process();}/*ARP answer*/
break;
case 0x0800:/*表示收到一个ip包*/
if(rxdnet.ipframe.destip[0]==my_ip_address.words[0])
if(rxdnet.ipframe.destip[1]==my_ip_address.words[1])
{
FunProcessIP();
}
default :break;
}
}
void create_ip_packet(union ip_address_type ip_add,uint length,uchar protocal)//tcp包的长度(不包括ip头),,ip协议段
{
//产生一个ip头
txdnet.etherframe.protocal=0x0800;//协议为ip协议
txdnet.ipframe.verandihl=0x45;//版本和头长度
txdnet.ipframe.ttl=128;//ttl
txdnet.ipframe.typeofserver=0x00;//服务类型
txdnet.ipframe.crc=0;
txdnet.ipframe.frameindex=frameindex++;
txdnet.ipframe.segment=0x4000;//没有分段
length=length+20;
txdnet.ipframe.totallength=length;
txdnet.ipframe.protocal=protocal;//下层协议
txdnet.ipframe.destip[0]=ip_add.words[0];//对方ip
txdnet.ipframe.destip[1]=ip_add.words[1];
txdnet.ipframe.sourceip[0]=my_ip_address.words[0];//本机ip
txdnet.ipframe.sourceip[1]=my_ip_address.words[1];
txdnet.ipframe.crc=createipheadcrc();
length=length+14;//6+6+2
send_packet(length);
txdnet.etherframe.length=length;
if((txdnet.tcpframe.tcpdata[2]==0x55) && (protocal==6) && (b_dvrcommand==0))
{copy_to_retransmit_buffer();}
b_dvrcommand=0;
}
void create_tcp_packet(unsigned char length)
{
txdnet.tcpframe.sourceport=local_use_port;
txdnet.tcpframe.destport=socketnumber;
txdnet.tcpframe.seqnumber=1;
txdnet.tcpframe.acknumber=1;
txdnet.tcpframe.offset=0x50;
txdnet.tcpframe.control=0x18;//tcp_ack; //syn+ack
txdnet.tcpframe.window=512;
txdnet.tcpframe.urg=0;
txdnet.tcpframe.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.ttl=0;
txdnet.ipframe.protocal=6;//tcp
txdnet.ipframe.crc=20+length;
txdnet.tcpframe.crc=createtcpcrc();
create_ip_packet(ping_ip_address,20+length,6);
}
void create_udp_packet(unsigned char length)
{
union ip_address_type temp_ip_address;
txdnet.udpframe.sourceport=udp_port;//local_use_port;
txdnet.udpframe.destport=udp_dstport;//rxdnet.udpframe.sourceport;//socketnumber;
txdnet.udpframe.length=8+length;
txdnet.udpframe.crc=0;
txdnet.ipframe.destip[0]=rxdnet.ipframe.sourceip[0];//ping_ip_address.words[0];
txdnet.ipframe.destip[1]=rxdnet.ipframe.sourceip[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.ttl=0;
txdnet.ipframe.protocal=17;//tcp
txdnet.ipframe.crc=8+length;
txdnet.udpframe.crc=createtcpcrc();
temp_ip_address.words[0]=rxdnet.ipframe.sourceip[0];
temp_ip_address.words[1]=rxdnet.ipframe.sourceip[1];
create_ip_packet(temp_ip_address,8+length,17);
}
unsigned int createtcpcrc()
{
unsigned int crc;
crc=checksum(&txdnet.ippacket.ippacket[4],txdnet.ipframe.crc+12);
return (crc);
}
void telnet_request(ulong ip_address,uint portnumber)
{
//请求连接到远程
uchar i;
tcp1024.dest_ip[0]=ip_address>>16;
tcp1024.dest_ip[1]=ip_address&0xffff;//对方的ip地址
for(i=0;i<3;i++)
{
tcp1024.dest_node_id[i]=dvr_ethernet_address.words[i];//对方的以太网地址或网关地址
}
tcp1024.my_port=Local_Dvr_Port;//本机端口
tcp1024.dest_port=portnumber;//对方端口
tcp1024.irs=0;//对方的初始化顺序号
tcp1024.rcv_nxt=0;//对方的顺序号,用于确认
tcp1024.iss=tcp1024.snd_nxt;//我的初始化顺序号
tcp1024.snd_una=tcp1024.iss;//我的未确认得序号
tcp1024.snd_nxt=tcp1024.iss+1;//我的顺序号,用于发送
tcp1024.rcv_wnd=0;//对方的window大小
tcp1024.snd_wnd=1024;//就是说我这边最大接受字节的包,用于流控
tcp1024.dest_max_segment_size=560;//默认为560
tcp1024.my_max_segment_size=1460;//我可以接受最大的以太网数据包
//===========建立应答帧
for(i=0;i<3;i++)
{
txdnet.etherframe.destnodeid[i]=tcp1024.dest_node_id[i];//目的网卡地址
}
txdnet.tcpframe.sourceport=tcp1024.my_port;
txdnet.tcpframe.destport=tcp1024.dest_port;
txdnet.tcpframe.seqnumber=tcp1024.iss;
txdnet.tcpframe.acknumber=tcp1024.rcv_nxt;
txdnet.tcpframe.offset=0x70;
txdnet.tcpframe.control=tcp_syn; //syn+ack
txdnet.tcpframe.window=tcp1024.snd_wnd;
txdnet.tcpframe.urg=0;
txdnet.tcpframe.crc=0;
txdnet.ippacket.ippacket[20]=0x0204;//tcp选项
txdnet.ippacket.ippacket[21]=tcp1024.my_max_segment_size;
txdnet.ippacket.ippacket[22]=0x0101;
txdnet.ippacket.ippacket[23]=0x0402;
txdnet.ipframe.destip[0]=tcp1024.dest_ip[0];
txdnet.ipframe.destip[1]=tcp1024.dest_ip[1];
txdnet.ipframe.sourceip[0]=my_ip_address.words[0];
txdnet.ipframe.sourceip[1]=my_ip_address.words[1];
txdnet.ipframe.ttl=0;
txdnet.ipframe.protocal=6;//tcp
txdnet.ipframe.crc=28;
txdnet.tcpframe.crc=createtcpcrc();
b_dvrcommand=1;
create_ip_packet(dvr_ip_address,28,6);
tcp1024.state=tcp_state_syn_sent;//tcp_syn_sent;
}
void process_telnet()
{
unsigned char j;
// if(tcp_count>0)
{
if(b_RunDvrCommand)return;
if(tcp_count>RetryTcp_Count)
{
if(ping_ip_address_ttl>1)
{
//表示ip地址已经解析
telnet_request(dvr_ip_address.dwords,Dvr_Port);
b_RunDvrCommand=1;
// send_tcpdata();
tcp_count=RetryTcp_Count;
c_DvrRunTime=2;
}
/* else
{
//解析ip地址
if((dvr_ip_address.dwords&mask_ip_address.dwords)==(my_ip_address.dwords&mask_ip_address.dwords))
{//表示位于同一子网.
ping_ip_address_ttl=1;
arp_request(dvr_ip_address.dwords);
}
else
{//表示属于不同的子网,需要通过网关.
ping_ip_address_ttl=10;
for(j=0;j<6;j++)
{
dvr_ethernet_address.bytes[j]=gateway_ethernet_address.bytes[j];
}
if(gateway_ip_address_ttl==0)
{
ping_ip_address_ttl=0;
}
}
tcp_count--;
}*/
}
else
{
if((b_RunDvrCommand==1)||(c_DvrReadBuffer==c_DvrWriteBuffer))
{tcp_count=RetryTcp_Count;}
else
{
dvr_ip_address.dwords=dvr_buffer[c_DvrReadBuffer].dstipaddress;
c_camnumber=dvr_buffer[c_DvrReadBuffer].cam_number;
c_DvrReadBuffer++;
if(c_DvrReadBuffer>=dvr_length)c_DvrReadBuffer=0;
tcp_count=RetryTcp_Count*2;
if((dvr_ip_address.dwords&mask_ip_address.dwords)==(my_ip_address.dwords&mask_ip_address.dwords))
{//表示位于同一子网.
ping_ip_address_ttl=1;
arp_request(dvr_ip_address.dwords);
}
else
{//表示属于不同的子网,需要通过网关.
ping_ip_address_ttl=10;
for(j=0;j<6;j++)
{
dvr_ethernet_address.bytes[j]=gateway_ethernet_address.bytes[j];
}
if(gateway_ip_address_ttl==0)
{
ping_ip_address_ttl=0;
}
}
}
}
}
}
void copy_to_retransmit_buffer()
{
uchar i;
uint ii;
uchar xdata *txd=&txdnet;
uchar xdata *rt;
// for(i=0;i<rt_size;i++)
{
i=txdnet.tcpframe.tcpdata[3];
// if(retransmit_buffer[i].rtframe.status==0)
{
rt=&retransmit_buffer[i].bytes.bytebuf;
for(ii=0;ii<retransmit_buffer[i].rtframe.length+4;ii++)
{
(*rt)=(*txd);
rt++;
txd++;
}
retransmit_buffer[i].rtframe.status=1;
retransmit_buffer[i].rtframe.timeout=rt_time;
}
}
}
void retransmit_packet(uchar i)
{
uint ii;
uchar xdata *txd=&txdnet;
uchar xdata *rt;
rt=&retransmit_buffer[i].bytes.bytebuf;
for(ii=0;ii<retransmit_buffer[i].rtframe.length+4;ii++)
{
(*txd)=(*rt);
rt++;
txd++;
}
send_packet(retransmit_buffer[i].rtframe.length);
retransmit_buffer[i].rtframe.timeout=rt_time;
//if(txdnet.tcpframe.tcpdata[2]==0x55){retransmit_buffer[i].rtframe.timeout=4;}
}
unsigned char FunCheckEmpty(void)
{
unsigned char i;
for(i=0;i<rt_size;i++)
{
if(retransmit_buffer[i].rtframe.status==0)
{
return i;
}
}
return rt_size;
}
unsigned char check_multi(void)
{
unsigned char i;
for(i=0;i<=rt_size;i++)
{
if(retransmitpacket[i].status!=0)
{
if(retransmitpacket[i].dstip[0]==rxdnet.ipframe.sourceip[0])
if(retransmitpacket[i].dstip[1]==rxdnet.ipframe.sourceip[1])
{
if(retransmitpacket[i].frameindex==rxdnet.ipframe.frameindex)
{
return 0;
}
}
}
}
return 1;
}
void protect_multi()
{
unsigned char i;
for(i=0;i<=rt_size;i++)
{
if(retransmitpacket[i].status==0)
{
retransmitpacket[i].status=1;
retransmitpacket[i].dstip[0]=rxdnet.ipframe.sourceip[0];
retransmitpacket[i].dstip[1]=rxdnet.ipframe.sourceip[1];
retransmitpacket[i].frameindex=rxdnet.ipframe.frameindex;
retransmitpacket[i].timeout=200;
break;
}
}
}
void FunAddCommand(unsigned char length)
{
unsigned char i;
if(b_cb_full)return;
for(i=0;i<length;i++)
{
rt_command_buffer[c_writecommand].command[i]=command_buffer[i+1];
}
rt_command_buffer[c_writecommand].command[i]=0;
rt_command_buffer[c_writecommand].dstipaddress=ping_ip_address.dwords;
c_writecommand++;
if(c_writecommand>=rt_cmd_length)c_writecommand=0;
if(c_writecommand==c_readcommand)b_cb_full=1;
}
void FunNetSendCommandBuffer(void)
{
unsigned char i,j;
unsigned long l_bakpingipaddress;
l_bakpingipaddress=ping_ip_address.dwords;
ping_ip_address.dwords=rt_command_buffer[c_readcommand].dstipaddress;
txdnet.tcpframe.tcpdata[0]=0x55;
txdnet.tcpframe.tcpdata[1]=0xaa;
txdnet.tcpframe.tcpdata[2]=0x55;
txdnet.tcpframe.tcpdata[3]=rt_size;
for(i=0,j=4;rt_command_buffer[c_readcommand].command[i]!=0;i++,j++){txdnet.tcpframe.tcpdata[j]=rt_command_buffer[c_readcommand].command[i];}
txdnet.tcpframe.tcpdata[j]='a';
c_readcommand++;
if(c_readcommand>=rt_cmd_length)c_readcommand=0;
c_txcount++;
//for(i=0;i<3;i++){txdnet.etherframe.destnodeid[i]=ping_ethernet_address.words[i];}
create_tcp_packet(j+1);
ping_ip_address.dwords=l_bakpingipaddress;
}
void FunCheckOnline(void)
{
if((ping_ip_address.dwords&mask_ip_address.dwords)==(my_ip_address.dwords&mask_ip_address.dwords))
{//表示位于同一子网.
if(((sec%2)==0) && (ping_ip_address_ttl<5))
{
arp_request(ping_ip_address.dwords);
}
}
else
{//表示属于不同的子网,需要通过网关.
if(gateway_ip_address_ttl==0)
{
ping_ip_address_ttl=0;
}
else{ping_ip_address_ttl=10;}
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -