📄 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 + -