📄 ppp.c
字号:
type = MainBuffer[i++];
len = MainBuffer[i++];
if (len < 2) len = 2;
dw = *(u32*)(MainBuffer + i); // get the ip they rejected
switch (type)
{
case 3 : // oh dear
if (dw && (dw != 0xffffffff))
PPP.OUR_IP.ip32 = 0; // try requesting a new ip then
else
{
PPP.OUR_IP.ip32 = 0xffffffff; //
PPP_End(); // terminate the link
goto ppp_end1;
}
break;
case 129 : if (dw && (dw != 0xffffffff))
PPP.DNS1_IP.ip32 = 0; // try requesting a new ip then
else
PPP.DNS1_IP.ip32 = 0xffffffff; // their is no primary DNS ip .. don't ask again
break;
case 131 : if (dw && (dw != 0xffffffff))
PPP.DNS2_IP.ip32 = 0; // try requesting a new ip then
else
PPP.DNS2_IP.ip32 = 0xffffffff; // their is no secondary DNS ip .. don't ask again
break;
}
i += len - 2;
}
u16_Put(&PPP.SendTick, PPP_Timeout); // send next packet asap
goto ppp_end1;
}
// **********************************************************
if ((CodeHeader->Code == PPP_CNAK) || (CodeHeader->Code == PPP_CACK))
{
i = MainBufferRd_Rx;
while ((i + 2) <= MainBufferWr_Rx)
{
type = MainBuffer[i++];
len = MainBuffer[i++];
if (len < 2) len = 2;
p = 0;
if (type == 3) p = &PPP.OUR_IP.ip32; // they are giving us our ip address
else
if (type == 129) p = &PPP.DNS1_IP.ip32; // they are giving us the primary dns ip address
else
if (type == 131) p = &PPP.DNS2_IP.ip32; // they are giving us the secondary dns ip address
if (p) memmove(p, MainBuffer + i, 4); // get ip address
i += len - 2;
}
if (CodeHeader->Code == PPP_CACK) PPP.AcceptedIPOptions = true;
u16_Put(&PPP.SendTick, PPP_Timeout); // send next packet asap
goto ppp_end1;
}
// **********************************************************
goto ppp_CodeReject; // should never get here
}
// ****************
// unknown protocol - reject it and send it back
ppp_Unknown:
#ifdef Debug
SendDebugRStr(UnknownProtocolStr);
#endif
w = PPP_PREJ;
w2 = InformationIndex - 2;
len = (MainBufferWr_Rx - InformationIndex) + 2;
goto ppp_end2;
// ****************
// unknown code - reject it and send it back
ppp_CodeReject:
#ifdef Debug
SendDebugRStr(UnknownCodeStr2);
#endif
w = PPP_CodeREJ;
w2 = InformationIndex;
len = MainBufferWr_Rx - InformationIndex;
// ***********************
// add the rejected packet - ready for sending back
ppp_end2:
MustByteStuff = true;
memmove(&MainBuffer[sizeof(T_PPP_Header1) + sizeof(T_CodeHeader)], &MainBuffer[w2], len);
PPP_StartPacket(PPP_LCP);
CodeHeader = (T_CodeHeader *)&MainBuffer[MainBufferWr_Tx];
PPP_AddCodeHeader(w);
MainBufferWr_Tx += len; // we previously moved the rejected packet into place
CodeHeader->Len += len;
CodeHeader->Len = htons(CodeHeader->Len); // correct byte order
PPP.OurID++;
// ***********************
// Send a tx packet back if we have one to send
ppp_end1:
if (MainBufferWr_Tx)
{ // if we have compiled a packet to send back, send it now
w = MainBufferWr_Tx;
if (PPP_SendPacket(MustByteStuff)) // send it
{
#ifdef Debug
PPP_DisplayPacket(true, w); //
#endif
}
}
MainBufferWr_Tx = 0; //
// **********************************
// reset ppp rx ready for next packet
PPP.RxStuff = false; // reset Rx stuff flag
PPP.RxFCS = HDLC_PPP_INIT_FCS_16; // init the Rx fcs
MainBufferWr_Rx = 0; // reset Rx buffer index
// **********************************
// terminate the ppp link if we have ben told too
if (Terminate) PPP_Reset(0, 0); // link is now closed
// **********************************
return true; // their was a packet
}
//**************************************************************************************
// call this from the main executive loop - as often as you can ... it'll take care of ALL the PPP stuff for you
// do NOT call this from an interrupt !!
void PPP_Process(void)
{
u8 c;
if (PPP.Stage == PPPS_None) return; // we haven't got a PPP conection going
// **********************************
// get any new data from the PPP uart
if (!MainBufferWr_Tx)
{
while (UART1_RxBufferRd != UART1_RxBufferWr)
{
c = (u8)UART1_RxBuffer[UART1_RxBufferRd++];
if (UART1_RxBufferRd >= sizeof(UART1_RxBuffer)) UART1_RxBufferRd -= sizeof(UART1_RxBuffer); // wap awound
if (PPP_AddNewRxByte(c)) break; // pass the byte onto the PPP RX routine
}
}
#ifdef ModemHandShaking
HardwareFlowControl(ModemUart); // tell em to stop sending data if our buffer is full
#endif
// **********************************
// take of sending PPP org packets (all the acks, naks, rejs are sent in rx routine)
if (PPP.NAK_REJ_Count >= PPP_Retries) goto ppp_end; // oh no !
if (u16_Get(&PPP.LastRxData) >= PPP_DataTimeout) //
{ //
MainBufferWr_Rx = -1; //
} //
if (MainBufferWr_Rx > 0) return; // we have data coming in - wait for it to be processed before using the buffer for sending a packet
if (u16_Get(&PPP.SendTick) < PPP_Timeout) return; // not time to retry
if ((PPP.Stage != PPPS_IP) && (PPP.Retries >= PPP_Retries)) //
{
#ifdef Debug
SendDebugRStr(PPPRetryFailStr);
#endif
switch (PPP.Stage)
{
case PPPS_None : break;
case PPPS_Start : PPP_Stage(PPPS_None);
break;
case PPPS_LCP : PPP_Reset(0, 0);
break;
case PPPS_LogOn :
case PPPS_IP_Addr :
case PPPS_IP : PPP_Stage(PPPS_Disc);
break;
case PPPS_Disc :
default : PPP_Reset(0, 0);
break;
}
return;
}
switch (PPP.Stage) //
{ //
case PPPS_Start : PPP_SendConfigRequest(); // request LCP options
break; //
case PPPS_LCP : if ((PPP.AcceptedTheirLCPOptions) && (PPP.AcceptedOurLCPOptions))
PPP_Stage(PPPS_LogOn); // onto next stage
else //
if (!PPP.AcceptedOurLCPOptions) //
PPP_SendConfigRequest(); // request LCP options
break; //
case PPPS_LogOn : if (PPP.AuthProtocol == PPP_PAP) //
PPP_SendPap(); // send our username/password
else //
{ //
#ifdef Debug //
SendDebugRStr(AuthNoNeedStr); //
#endif //
PPP_Stage(PPPS_IP_Addr); // onto next stage - without logging on
} //
break; //
case PPPS_IP_Addr : if (!PPP.AcceptedIPOptions) //
{
PPP_SendIPRequest(); // ask for ip addresses
break;
}
#ifdef Debug
sprintf((char*)ScratchPad, "\n Tx Magic Num: %lu\n", PPP.TxMN);
SendDebugStr((char*)ScratchPad);
sprintf((char*)ScratchPad, " Rx Magic Num: %lu\n", PPP.RxMN);
SendDebugStr((char*)ScratchPad);
strcpy((char*)ScratchPad, "\n Tx ACCM: ");
bin2bstr(ScratchPad + strlen((char*)ScratchPad), PPP.TxACCM, 32);
strcat((char*)ScratchPad, "\n Rx ACCM: ");
bin2bstr(ScratchPad + strlen((char*)ScratchPad), PPP.RxACCM, 32);
strcat((char*)ScratchPad, "\n");
SendDebugStr((char*)ScratchPad);
sprintf((char*)ScratchPad, "\n Tx MRU: %u\n", PPP.TxMRU);
SendDebugStr((char*)ScratchPad);
sprintf((char*)ScratchPad, " Rx MRU: %u\n\n", PPP.RxMRU);
SendDebugStr((char*)ScratchPad);
if (Flags1 & (1<<Flags1_Debug)) PPP_DisplayIP();
#endif
IP_ID = rand(); //
PPP_Stage(PPPS_IP); // onto next stage
//
#ifdef Debug
SendDebugRStr(WeAreInStr);
#endif
#ifdef IncludeTCP
TCP_Socket = TCP_SocketListen(TCP_Port); // open a tcp listening socket
#endif
break; //
case PPPS_IP : IP_Process(); //
//
if (u32_Get(&PPP.LCP_Echo_Timer) >= PPP_LCP_Echo_RetryTime) //
{ //
PPP_SendEchoRequest(); // send an echo request
} //
break; //
case PPPS_Disc : IP_Process(); //
#ifdef IncludeTCP
if (TCP_CloseSocket(TCP_Socket)) PPP_SendTermRequest(); // teminate the link
#else
PPP_SendTermRequest();
#endif
break; //
default : PPP_Stage(PPPS_None); // fix it
break; //
} //
return;
ppp_end:
PPP_End(); // give up
}
//**************************************************************************************
// call this every 10ms - from a timer interrupt say
void PPP_10ms_Timer(void)
{
if (PPP.Stage == PPPS_None) return;
if (PPP.LastRxData < 65000) PPP.LastRxData += 10;
if (PPP.SendTick < 65000) PPP.SendTick += 10;
if (PPP.Stage == PPPS_IP)
{
if (PPP.LCP_Echo_Timer < PPP_LCP_Echo_RetryTime) PPP.LCP_Echo_Timer += 10;
}
if ((PPP.Stage == PPPS_IP) || (PPP.Stage == PPPS_Disc))
{
IP_10ms_Timer();
}
}
//**************************************************************************************
// call this to reset/clear the PPP details ready for connecting
void PPP_Reset(char *Username, char *Password)
{
int i;
u32 TxBytes, RxBytes;
TxBytes = PPP.TxBytes;
RxBytes = PPP.RxBytes;
#ifdef Debug
if ((PPP.TxBytes) || (PPP.RxBytes))
{
SendDebugRStr(TxBytesStr);
sprintf((char*)ScratchPad, "%lu ", PPP.TxBytes);
SendDebugStr((char*)ScratchPad);
SendDebugRStr(RxBytesStr);
sprintf((char*)ScratchPad, "%lu\n", PPP.RxBytes);
SendDebugStr((char*)ScratchPad);
}
#endif
if (PPP.Stage != PPPS_None) PPP_Stage(PPPS_None);
memset(&PPP, 0, sizeof(T_PPP));
PPP.TxBytes = TxBytes;
PPP.RxBytes = RxBytes;
if (Username)
{ // save the username to log on with
i = sizeof(PPP.Username);
if (strlen(Username) >= i)
strncpy((char*)PPP.Username, Username, i - 1);
else
strcpy((char*)PPP.Username, Username);
}
if (Password)
{
i = sizeof(PPP.Password);
if (strlen(Password) >= i)
strncpy((char*)PPP.Password, Password, i - 1);
else
strcpy((char*)PPP.Password, Password);
}
PPP.Stage = PPPS_None; //
u16_Put(&PPP.SendTick, PPP_Timeout); // send next packet asap
u16_Put(&PPP.LastRxData, 0); //
u32_Put(&PPP.LCP_Echo_Timer, 0); //
PPP.TxMRU = 1500; // max size of packet we will send
PPP.RxMRU = OurRxMRU; // max size of packet we can accept
PPP.TxMN = Random32; // get a random 32-bit value
rmemcpy((char*)&PPP.OUR_IP.ip32, OurIP, 4); // set the ip's
rmemcpy((char*)&PPP.DNS1_IP.ip32, Dns1IP, 4); //
rmemcpy((char*)&PPP.DNS2_IP.ip32, Dns2IP, 4); //
#ifdef IncludeTCP
#ifndef StaticTCPSocket
if (TCP_Socket != NULL)
{
realloc(TCP_Socket, 0);
TCP_Socket = NULL;
}
#endif
#endif
MainBufferWr_Rx = -1;
MainBufferWr_Tx = 0;
UART1_RxBufferRd = 0;
UART1_RxBufferWr = 0;
}
//**************************************************************************************
// call this when you want to start a PPP session
#ifdef CPU_eZ8
void PPP_Start(char rom *Username, char rom *Password)
#endif
#ifdef CPU_ATmega128
void PPP_Start(const char *Username, const char *Password)
#endif
{
char un[32] = {""};
char pw[32] = {""};
if (PPP.Stage != PPPS_None) return; // PPP is already busy
//
if (Username) rstrcpy(un, Username); // copy the text into ram
if (Password) rstrcpy(pw, Password); // copy the text into ram
//
PPP_Reset(un, pw); //
//
PPP_Stage(PPPS_Start); // start a PPP log on
}
//**************************************************************************************
// call this to end a PPP session
void PPP_End(void)
{
switch (PPP.Stage)
{
case PPPS_None : break;
case PPPS_Start : PPP_Stage(PPPS_None);
break;
case PPPS_LCP :
case PPPS_LogOn :
case PPPS_IP_Addr :
case PPPS_IP : PPP_Stage(PPPS_Disc);
break;
case PPPS_Disc : break;
default : PPP_Reset(0, 0);
break;
}
}
//***********************************************************
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -