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

📄 protocol.c

📁 利用51单片机对RTL8109进行控制
💻 C
📖 第 1 页 / 共 3 页
字号:
	{
		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 + -