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

📄 connection.c

📁 embedded ethernet code for pic18F
💻 C
📖 第 1 页 / 共 2 页
字号:
// module implementing the TCP and UDP stacks.  Uses info provided in sockets.c to invoke sockets as appropriate

#include <p18cxxx.h>
#include <delays.h>
#include "nic.h"
#include "network.h"
#include "sockets.h"
#include <usart.h>


extern SOCKETINFO socketInfo[];


//void send_tcp_packet(unsigned int,unsigned int,unsigned long,unsigned long,FLAGS);
void send_tcp_packet(unsigned char *,unsigned int,unsigned int,unsigned char,FLAGS);




//******************************************************************
//*	TCP Header Layout
//******************************************************************
#define	TCP_srcport			   0x22	//TCP source port
#define	TCP_destport   	   0x24	//TCP destination port
#define	TCP_seqnum  	      0x26	//sequence number
#define	TCP_acknum	         0x2A	//acknowledgement number
#define	TCP_hdrflags			0x2E	//4-bit header len and flags
#define	TCP_window			   0x30	//window size
#define	TCP_cksum		      0x32	//TCP checksum
#define	TCP_urgentptr   		0x34	//urgent pointer
#define  TCP_data             0x36  //option/data
//******************************************************************
//*	TCP Flags
//*   IN flags represent incoming bits
//*   OUT flags represent outgoing bits
//******************************************************************
#define  FIN_IN               (packet[TCP_hdrflags+1]&0b00000001)
#define  SYN_IN               (packet[TCP_hdrflags+1]&0b00000010)
#define  RST_IN               (packet[TCP_hdrflags+1]&0b00000100)
#define  PSH_IN               (packet[TCP_hdrflags+1]&0b00001000)
#define  ACK_IN               (packet[TCP_hdrflags+1]&0b00010000)
#define  URG_IN               (packet[TCP_hdrflags+1]&0b00100000)
#define  FIN_OUT              (packet[TCP_hdrflags+1]|=0b00000001)
#define  SYN_OUT              (packet[TCP_hdrflags+1]|=0b00000010)
#define  RST_OUT              (packet[TCP_hdrflags+1]|=0b00000100)
#define  PSH_OUT              (packet[TCP_hdrflags+1]|=0b00001000)
#define  ACK_OUT              (packet[TCP_hdrflags+1]|=0b00010000)
#define  URG_OUT              (packet[TCP_hdrflags+1]|=0b00100000)
//******************************************************************
//*	UDP Header
//******************************************************************
#define	UDP_srcport			   0x22
#define	UDP_destport			UDP_srcport+2
#define	UDP_len				   UDP_destport+2
#define	UDP_cksum			   UDP_len+2
#define	UDP_data			      UDP_cksum+2


unsigned long makeACKOrSEQ(unsigned char *data)
{
	unsigned long ret=0;
	unsigned char i;
	
	for(i=0;i<4;i++) ret=(ret<<8)|(unsigned long)data[i];
	return ret;
}



unsigned int computeIPHeaderChecksum(unsigned char *packet)
{
	unsigned long hdr_chksum;
	unsigned int chksum16;
	signed int tcplen;
	
	//hdr_chksum=computeIPChecksum(packet+ip_srcaddr,0,0x08);
    //hdr_chksum = hdr_chksum + packet[ip_proto];
    
    hdr_chksum=computeIPContributionToChecksum(packet);
    
    switch(getIPDatagramType(packet))
    {
	    case TCP:
	    	tcplen = getIPDatagramPayloadLength(packet);
    		hdr_chksum = hdr_chksum + tcplen;
    		hdr_chksum=computeIPChecksum(packet+TCP_srcport,hdr_chksum,tcplen);
    		break;
    	case UDP:
    		hdr_chksum=computeIPChecksum(packet+UDP_len,hdr_chksum,0x02);
      		hdr_chksum=computeIPChecksum(packet+UDP_srcport,hdr_chksum,(((unsigned int)packet[UDP_len])<<8)|packet[UDP_len+1]);
    		break;
    }
    chksum16= ~(hdr_chksum + ((hdr_chksum & 0xFFFF0000) >> 16));
    return chksum16;
}


//******************************************************************
//*	TCP Function
//*   This function uses TCP protocol to act as a Telnet server on
//*   port 8088 decimal.  The application function is called with
//*   every incoming character.
//******************************************************************/

unsigned char matchSocket(unsigned int port)
{
	unsigned char i;
	
	
	for(i=0;i<NSOCKETS;i++) if(port==socketInfo[i].port) return i;
	return 255;
}

unsigned char matchSocketToPacket(unsigned int port,unsigned int sourcePort,unsigned char *srcIP)
{
	unsigned char i;
	
	if(srcIP==0) // find any unused slot for this socket
	{
		for(i=0;i<NSOCKETS;i++) if((!socketInfo[i].est)&&(port==socketInfo[i].port)) return i;
		return 255;
	}
	else // check that there is a used socket that maps precisely to this one
	{
		for(i=0;i<NSOCKETS;i++) if((matchIP(socketInfo[i].ip,srcIP))&&(sourcePort==socketInfo[i].srcPort)&&(port==socketInfo[i].port)) return i;
		return 255;
	}
}

// rather simple-minded Round-Robin approach to deciding which server to interrogate for data next

unsigned char getNextSocket(void)
{
	static unsigned char nextSocket=0;
	
	nextSocket=(nextSocket+1)%NSOCKETS;
	
	return nextSocket;
}
	
	
void doSyn(unsigned char *packet,unsigned char s,unsigned char inBytes)
{
	  unsigned char i;
	  static unsigned int ISN=0x1234;
	  
	  FLAGS flags;
	 
	  //putrsUSART("Received SYN\r\n");
	  
      if(!socketInfo[s].est)
      {
        socketInfo[s].syn=1;
        socketInfo[s].fin=0;
        
        // assemble client IP
      
        getIPDatagramSourceAddr(packet,socketInfo[s].mac,socketInfo[s].ip);
        socketInfo[s].srcPort=(((unsigned int)packet[TCP_srcport])<<8)|packet[TCP_srcport+1];
      }

      if(++ISN == 0x0000 || ++ISN == 0xFFFF) ISN = 0x1234;
      socketInfo[s].seq=(((unsigned long)ISN)<<16)|0xffff;
      socketInfo[s].clientSeq=makeACKOrSEQ(packet+TCP_seqnum)+1;
      
      if(socketInfo[s].est)
      {
	      flags.syn=0;
	      flags.rst=1;
	  }
	  else
	  {
		  flags.syn=1;
		  flags.rst=0;
	  }
      flags.fin=0;
      flags.ack=1;
      flags.push=0;
           
      //send_tcp_packet(1,make16(packet[ip_pktlen],packet[ip_pktlen+1])-40,socketInfo[s].seq,socketInfo[s].clientSeq,flags);
      send_tcp_packet(packet,1,getIPDatagramLength(packet)-40,s,flags);
      
      
   }
   
  
void doAck(unsigned char *packet,unsigned char s,unsigned int inBytes)
{
	unsigned int outBytes;
	unsigned long ackIn;
	FLAGS flags;
	
	flags.syn=0;
    flags.rst=0;
    flags.fin=0;
    flags.ack=1;
    
	if(PSH_IN) flags.push=1;
	else flags.push=0;
	   
	   //putrsUSART("Received ACK\r\n");
	   
	   if((inBytes == 0)&&(socketInfo[s].syn)) 
       {
        //assemble the acknowledgment number from the incoming packet
        ackIn =makeACKOrSEQ(packet+TCP_acknum);
        //if the incoming packet is a result of session establishment

	        flags.syn=1;
	        socketInfo[s].putData(0,&flags,packet+TCP_data);
	        outBytes=socketInfo[s].getData(&flags,packet+TCP_data);
	        //putrsUSART("Output ");printByte(outBytes>>8);printByte(outBytes&0xff);putrsUSART(" bytes\r\n");
	        //outBytes=socketInfo[s].callback(0,&flags,packet+TCP_data);
	        flags.syn=0;
        	if(flags.fin) socketInfo[s].fin=1;
	       // run the TCP application - if it sends a FIN, note this fact
           
           
           //clear the SYN flag
           
           socketInfo[s].syn=0; 
           
           //the incoming acknowledgment is my new sequence number
           
           socketInfo[s].seq=ackIn;
           socketInfo[s].clientSeq=makeACKOrSEQ(packet+TCP_seqnum);
        
           //expect to get an acknowledgment of the banner message
           socketInfo[s].ack=socketInfo[s].seq+outBytes; 

           //send the TCP/IP packet
           
           //send_tcp_packet(inBytes,outBytes,socketInfo[s].seq,socketInfo[s].clientSeq,flags);
           send_tcp_packet(packet,inBytes,outBytes,s,flags);
           socketInfo[s].seq+=outBytes;
           socketInfo[s].est=1; 
           
           
      }
      
      else if((inBytes!=0)&&(socketInfo[s].est))
      {
	      // run the TCP application - if it sends a FIN, note this fact
        //outBytes=socketInfo[s].callback(inBytes,&flags,packet+TCP_data);
        socketInfo[s].putData(inBytes,&flags,packet+TCP_data);
	    outBytes=socketInfo[s].getData(&flags,packet+TCP_data);
        if(flags.fin) socketInfo[s].fin=1;
         
        //assemble the acknowledgment number from the incoming packet
        ackIn =makeACKOrSEQ(packet+TCP_acknum);

        //check for the number of bytes acknowledged
        //determine how many bytes are outstanding and adjust the outgoing sequence number accordingly
        
        //if(ackIn <= socketInfo[s].ack) socketInfo[s].seq=socketInfo[s].ack-(socketInfo[s].ack-ackIn);
        if(ackIn <= socketInfo[s].ack) socketInfo[s].seq=ackIn;

        //my expected acknowledgement number
        
        socketInfo[s].clientSeq=makeACKOrSEQ(packet+TCP_seqnum)+inBytes;
        socketInfo[s].ack=socketInfo[s].seq+outBytes;
        //send_tcp_packet(inBytes,outBytes,socketInfo[s].seq,socketInfo[s].clientSeq,flags);
        send_tcp_packet(packet,inBytes,outBytes,s,flags);
        socketInfo[s].seq+=outBytes;
       }
  }
   
void doFinAck(unsigned char *packet,unsigned char s,unsigned int inBytes)
{
	unsigned long ackIn;
	FLAGS flags;
	
	//putrsUSART("Received FIN ACK\r\n");
	
	flags.syn=0;
    flags.rst=0;
    flags.fin=0;
    flags.ack=1;
    if(PSH_IN) flags.push=1;
    else flags.push=0;
	
	socketInfo[s].clientSeq=makeACKOrSEQ(packet+TCP_seqnum)+1;
    //send_tcp_packet(1,0,socketInfo[s].seq,socketInfo[s].clientSeq,flags);
    send_tcp_packet(packet,1,0,s,flags);
    socketInfo[s].fin=0;
    socketInfo[s].est=0;
    
}


void doFin(unsigned char *packet,unsigned char s,unsigned int inBytes)
{
	unsigned int outBytes=0;
	unsigned long ackIn;
	FLAGS flags;
	
	//putrsUSART("Received FIN\r\n");
	
	if(socketInfo[s].est)
	{
	  flags.syn=0;
      flags.rst=0;
      flags.fin=1;
      flags.ack=1;
      flags.push=1;
	
      //outBytes=socketInfo[s].callback(inBytes,&flags,packet+TCP_data);
	  socketInfo[s].putData(inBytes,&flags,packet+TCP_data);
	  outBytes=socketInfo[s].getData(&flags,packet+TCP_data);
      


      ackIn =makeACKOrSEQ(packet+TCP_acknum);
      
      //if(ackIn <= socketInfo[s].ack) socketInfo[s].seq=socketInfo[s].ack-(socketInfo[s].ack-ackIn);   
      if(ackIn <= socketInfo[s].ack) socketInfo[s].seq=ackIn;
      
      socketInfo[s].ack=socketInfo[s].seq+outBytes;
      		socketInfo[s].clientSeq=makeACKOrSEQ(packet+TCP_seqnum)+inBytes;
      
      
      //send_tcp_packet(inBytes,outBytes,socketInfo[s].seq,socketInfo[s].clientSeq,flags);
      send_tcp_packet(packet,inBytes,outBytes,s,flags);
      socketInfo[s].seq+=outBytes;
      socketInfo[s].est=0;
      
    }
      
}

void doUnsolicitedSend(unsigned char *packet,unsigned char s)
{
	unsigned int outBytes;
	

⌨️ 快捷键说明

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