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

📄 ppp._c

📁 在串口上PPP拨号上网的源程序(实现PPP协议栈)
💻 _C
字号:
#include "PPP.h"
#include "UART.h"

BYTE PPPStatus = 0;
BYTE InBuffer [PPP_BUFFER_SIZE + 1];	//PPP数据输入缓冲
BYTE OutBuffer[PPP_BUFFER_SIZE + 1];	//PPP数据输出缓冲
static  BYTE 	FrameSize = 0;          
static  BYTE    *PPP_Packet = InBuffer;
extern  WORD MRU=PPP_BUFFER_SIZE;
BYTE local_IPAddress[4];   //本地IP
BYTE remote_IPAddress[4];  //远端IP
extern BYTE UART_BUFFER[PPP_BUFFER_SIZE+3];
WORD UART_ptr=0;



void PPPInit (void) {
	PPPStatus |= ReSync;
}

void PPPEntry (void) {    
		if (PPPStatus & IsFrame) {                             //判断是否收到一个完整的PPP包
		switch (((((WORD)InBuffer [2])<<8)+InBuffer [3])) {                    //判断协议域

				case PPPID_LCP:	                       //是LCP的包
					HandleLCPOptions ();
				break;

				case PPPID_IPCP:  			//是IPCP的包
					HandleIPCPOptions ();
				break;
				
				case PPPID_IP:			        //是IP的包
				                                        //NNOS接口
				break;
				
				default:
					  RejectProtocol (InBuffer);	//拒绝协议 
				break;
			};
			
			PPPStatus &= ~IsFrame;
			PPPStatus |= ReSync;
		}

}
void Move (BYTE *src, BYTE *dest, register numBYTEs) {
	if ( numBYTEs <= 0 ) return;
	if ( src < dest ) {
		src += numBYTEs;
		dest += numBYTEs;
		do {
		*--dest = *--src;
		} while ( --numBYTEs > 0 );
	} else
		do {
		     *dest++ = *src++;
		} while ( --numBYTEs > 0 );
}

WORD PPPGetChecksum (register unsigned char *cp, register int len) {
	   return ~PPPfcs16(0xffff, cp, len );
}

static WORD PPPfcs16 (WORD fcs, BYTE *cp, int len) {
	   while (len--) 
		   fcs = (fcs >> 8) ^ fcstab[(fcs ^ *cp++) & 0xff];
       return (fcs);
}


/////////////////////////////////////////////////////////////
/*

PPP包发送
说明:0x00~0x20是ASCⅡ的控制字符,要进行转意处理。 

*/
////////////////////////////////////////////////////////////
void ProcPPPSend (BYTE *Buffer, BYTE len) 
{
	WORD Checksum = 0;
	Checksum = PPPGetChecksum (Buffer, Buffer[7] + 4);
	Buffer [Buffer[7]+4] = Checksum & 0xFF;
	Buffer [Buffer[7]+5] = (Checksum >> 8) & 0xFF;
	putchar (0x7E);
	while (len--) {
		if(*Buffer < 0x20)
		{    
			putchar(0x7D);
			putchar(*Buffer ^ 0x20);
		} 	
		else {
			switch (*Buffer) {
				case 0x7E:
					putchar (0x7D);
					putchar (0x5E);
				    break;
				case 0x7D:
					putchar (0x7D);
					putchar (0x5D);
				    break;
				default:
					putchar (*Buffer);
				    break;
			 }
		}
		Buffer++;
	}
	putchar (0x7E);
}




void ProcPPPReceive (void)
 {  

	BYTE c;
 	c=UART_BUFFER[UART_ptr];
	PPPStatus |= ByteRx;                //收到一个字节
	if (PPPStatus & IsFrame) return;    //判断是否收到一个完整的PPP包
	else
	{
	 if(UART_ptr>(PPP_BUFFER_SIZE+3))
	{
	UART_ptr=0;
	}
	UART_BUFFER[UART_ptr]='\0';
	UART_ptr++;
	}

	///////////////////////////////////////////////////////
	if (PPPStatus & ReSync) {           //判断是否在初始状态
		if (c!= 0x7E) return;      //判断是否包头
		PPPStatus &= ~ReSync;       //去掉初始状态
		FrameSize = 0;              //清空缓冲区
	}
   //////////////////////////////////////////////////////
	if (PPPStatus & IsESC) {                            //判断是否需要还原
		PPP_Packet [FrameSize++] = 0x20 ^ c;        //还原
		PPPStatus &= ~IsESC;                        //去掉还原状态
	}
	else {
		switch (c) {
			case ESC:		            // 如果是0x7D,置为还原状态
				PPPStatus |= IsESC;    
			break;

			case END:		            // 如果是0x7E,置为收到完整的PPP状态
				if (FrameSize > 0) {	
					PPP_Packet [FrameSize] = 0;
					PPPStatus |= IsFrame;	
				}
			break;

			default:                            //接收PPP数据
				PPP_Packet [FrameSize++] = c;
				if (FrameSize > (PPP_BUFFER_SIZE - 6)) {     //?
					FrameSize = 0;                   //清空缓冲区
					PPPStatus |= ReSync;             //置为初始状态
				}
			break;
		}
        }


}



static void HandleLCPOptions (void) {
WORD length0=0;                     //保存LCP的数据长度
WORD length1=8;                     //保存单个LCP包开始位置
BYTE rej=0;                         //是否要发拒绝包
BYTE nak=0;                         //是否要发否定包
BYTE i=0;                           
BYTE j=0;                              
BYTE temp_buffer1[20];              //LCP 协商类型
WORD temp_buffer2[20];              //LCP 各个协商类型在缓冲中的位置


	switch (InBuffer [4] ) {

		//++++++++++++++++++++++++++++++++++++++++++++++++++++
		case LCP_TERMINATE_REQUEST:			//"Server Terminate-Request received"
			Move (InBuffer, OutBuffer, InBuffer[7]+4);
			OutBuffer [4] = LCP_TERMINATE_ACK;
			ProcPPPSend ((BYTE *)OutBuffer, OutBuffer[7] + 6);					
			PPPStatus &= ~LinkOn;
		break;

		//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
		case LCP_CONFIG_REQUEST:
		      length0=InBuffer[7]-4;                  //LCP的数据长度
			  while(length0)                     
			  {
			    temp_buffer1[j]=InBuffer[length1];//读取LCP 协商类型
			    temp_buffer2[j]=length1;          //读取LCP 各个协商类型在缓冲中的位置
			    length0-=InBuffer[length1+1];     //
			    length1+=InBuffer[length1+1];     //
			    j++;
			  }//end of while(length0)
			  Move (InBuffer, OutBuffer, 8);
			  length1=8;
			  OutBuffer[7]=4;
			  for(i=0;i<j;i++)
			  {
			  if(!((temp_buffer1[i]==LCP_OPT_MRU)
			  ||(temp_buffer1[i]==LCP_OPT_ASYNC_MAP)
			  ||(temp_buffer1[i]==LCP_OPT_MAGIC)))
			   {
				Move (&InBuffer[temp_buffer2[i]],&OutBuffer[length1],InBuffer[temp_buffer2[i]+1]);
			        OutBuffer[7]+=InBuffer[temp_buffer2[i]+1];
				length1+=InBuffer[temp_buffer2[i]+1];    
			        rej = 1;
			   }//end of if((temp_buffer1[i]!=0x01)||(temp_buffer1[i]!=0x02)||(temp_buffer1[i]!=0x05))
			  }//end of for(i=0;i<j;i++)
			   if(rej == 1)
			   {
			    OutBuffer [4] = LCP_CONFIG_REJECT;
			    ProcPPPSend ((BYTE *)OutBuffer, OutBuffer[7] + 6);	
				return;
			   }//end of if(rej == 1)
			   
			   for(i=0;i<j;i++)
			   {
				 if(temp_buffer1[i]==LCP_OPT_MRU)
				 {
				  
				  if(((((WORD)InBuffer[temp_buffer2[i]+2])<<8)+InBuffer [temp_buffer2[i]+3])>MRU)
				  {
				  Move (&InBuffer[temp_buffer2[i]],&OutBuffer[length1],InBuffer[temp_buffer2[i]+1]);
			          OutBuffer[7]+=InBuffer[temp_buffer2[i]+1];
				  OutBuffer[length1+2]=MRU>>8;
				  OutBuffer[length1+3]=MRU;
				  length1+=InBuffer[temp_buffer2[i]+1];   
				  nak=1;
				  }
				  
				 }
				 if(temp_buffer1[i]==LCP_OPT_ASYNC_MAP)
				 {
				  if((InBuffer[temp_buffer2[i]+2]!=0x00)||
				  (InBuffer[temp_buffer2[i]+3]!=0x00)||
				  (InBuffer[temp_buffer2[i]+4]!=0x00)||
				  (InBuffer[temp_buffer2[i]+5]!=0x00)
				  )
				  {
				  Move (&InBuffer[temp_buffer2[i]],&OutBuffer[length1],InBuffer[temp_buffer2[i]+1]);
			          OutBuffer[7]+=InBuffer[temp_buffer2[i]+1];
				  OutBuffer[length1+2]=0x00;
				  OutBuffer[length1+3]=0x00;
				  OutBuffer[length1+4]=0x00;
				  OutBuffer[length1+5]=0x00;
				  length1+=InBuffer[temp_buffer2[i]+1];   
				  nak=1;
				 }//end of if((InBuffer[temp_buffer2[i]+2]!==0x00)||...
				 }//end of if(temp_buffer1[i]==02)
				 }//end of for(i=0;i<j;i++)
				 if(nak==1)
			      {
			       OutBuffer [4] = LCP_CONFIG_NAK;
			       ProcPPPSend ((BYTE *)OutBuffer, OutBuffer[7] + 6);	
				   return;
			      } 
			      
			 for(i=0;i<j;i++)
			  {
			   if((temp_buffer1[i]==LCP_OPT_MAGIC))
			    {
			     remote_magic_num[0]=InBuffer[temp_buffer2[i]+2];
			     remote_magic_num[1]=InBuffer[temp_buffer2[i]+3];
			     remote_magic_num[2]=InBuffer[temp_buffer2[i]+4];
	                     remote_magic_num[3]=InBuffer[temp_buffer2[i]+5];
			    }
			  }
				 
			 Move (InBuffer, OutBuffer, InBuffer[7]+4);
			 OutBuffer [4] =  LCP_CONFIG_ACK;
			 ProcPPPSend ((BYTE *)OutBuffer, OutBuffer[7] + 6);		
        break;
		//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
		case LCP_CONFIG_ACK:

		     while(length0)
			  {
			    temp_buffer1[j]=InBuffer[length1];
				temp_buffer2[j]=length1;
				length0-=InBuffer[length1+1];
				length1+=InBuffer[length1+1];
				j++;
			  }//end of while(length0)
			  if((temp_buffer1[i]==LCP_OPT_MRU))
			    {
				 MRU=((((WORD)InBuffer[temp_buffer2[i]+2])<<8)+InBuffer [temp_buffer2[i]+3]);
				}
			 IPAssignPacket();
			 		
		break;

		//++++++++++++++++++++++++++++++++++++++++++++++++++++
		case LCP_CONFIG_NAK:	
		           local_magic_num[0]=InBuffer[10];
			       local_magic_num[1]=InBuffer[11];
			       local_magic_num[2]=InBuffer[12];
	               local_magic_num[3]=InBuffer[13];
			   Move (InBuffer, OutBuffer, InBuffer[7]+4);
			   OutBuffer[4]=LCP_CONFIG_REQUEST;
			   ProcPPPSend ((BYTE *)OutBuffer, OutBuffer[7] + 6);
		break;

		//++++++++++++++++++++++++++++++++++++++++++++++++++++
		case LCP_CONFIG_REJECT:
		break;
		
		//++++++++++++++++++++++++++++++++++++++++++++++++++++
		case LCP_TERMINATE_ACK:			// Terminate ACK!
			PPPStatus &= ~LinkOn;
		break;
	}
	return;
}

static void HandleIPCPOptions (void) {

WORD length0=0;
WORD length1=8;
BYTE rej=0;
BYTE nak=0;
BYTE i=0;
BYTE j=0;
BYTE temp_buffer1[20];
WORD temp_buffer2[20];

	switch (InBuffer [4] ) {
		case IPCP_CONFIG_REQUEST:
		     length0=InBuffer[7]-4;
			  while(length0)
			  {
			    temp_buffer1[j]=InBuffer[length1];
				temp_buffer2[j]=length1;
				length0-=InBuffer[length1+1];
				length1+=InBuffer[length1+1];
				j++;
			  }//end of while(length0)
		     for(i=0;i<j;i++)
			 {
			   if(temp_buffer1[i]==0x02)
			   {
			    Move (&InBuffer[temp_buffer2[i]],&OutBuffer[length1],InBuffer[temp_buffer2[i]+1]);
			    OutBuffer[7]+=InBuffer[temp_buffer2[i]+1];
				length1+=InBuffer[temp_buffer2[i]+1];    
			    rej = 1;
			   }
			 }
			   if(rej == 1)
			   {
			    OutBuffer [4] = LCP_CONFIG_REJECT;
			    ProcPPPSend ((BYTE *)OutBuffer, OutBuffer[7] + 6);	
				return;
			   }//end of if(rej == 1)
			   
		     if (InBuffer [8] == 0x03) {			// Reply of the only IPCP Request we can send
				remote_IPAddress [0] = InBuffer [10];		// ISP assigned IP address
				remote_IPAddress [1] = InBuffer [11];		
				remote_IPAddress [2] = InBuffer [12];
				remote_IPAddress [3] = InBuffer [13];
				Move (InBuffer, OutBuffer, InBuffer[7]+4);
				OutBuffer[4]=IPCP_CONFIG_ACK;
				ProcPPPSend ((BYTE *)OutBuffer, OutBuffer[7] + 6);
				PPPStatus |= LinkOn;			// PPP Link is now up
			} 	
			
		break;

		case IPCP_CONFIG_ACK:
			if (InBuffer [8] == 3) {			// Reply of the only IPCP Request we can send
				local_IPAddress [0] = InBuffer [10];		// ISP assigned IP address
				local_IPAddress [1] = InBuffer [11];		
				local_IPAddress [2] = InBuffer [12];
				local_IPAddress [3] = InBuffer [13];
				
			}
		break;

		case IPCP_CONFIG_NAK:
			if (InBuffer [8] == 0x03) {
					/// Request IP Address ////
					Move (InBuffer, OutBuffer, InBuffer[7]+6);
					OutBuffer [4] = IPCP_CONFIG_REQUEST;
					ProcPPPSend ((BYTE *)OutBuffer, OutBuffer[7] + 6);
			}
		break;
		
		case IPCP_CONFIG_REJECT:
		break;
	}

}

⌨️ 快捷键说明

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