📄 ppp.c
字号:
u8 c;
u16 fcs;
u8 *Buffer;
u16 Len;
Buffer = MainBuffer; //
Len = MainBufferWr_Tx; //
if (Len == 0) return true; // no data to send
fcs = HDLC_PPP_INIT_FCS_16; // init the fcs
if (!PPP_SendByte(PPP_Flag)) return false; // start flag
for (; Len; Len--)
{
c = *Buffer++; // byte to send
fcs = UpdateFCS_16(fcs, c); // update the FCS
if (!PPP_TxByte(c, MustByteStuff)) return false; // data
}
fcs = ~fcs; // finalize the fcs
if (!PPP_TxByte((u8)(fcs & 0xff), MustByteStuff)) return false; // fcs LS-Byte
if (!PPP_TxByte((u8)((fcs >> 8) & 0xff), MustByteStuff)) return false; // fcs MS-Byte
MainBufferWr_Tx = 0; //
return PPP_SendByte(PPP_Flag); // stop flag
}
//****************************************************************************
void PPP_StartPacket(u16 Protocol)
{ // start a PPP packet off
MainBufferWr_Tx = 0; //
PPPHeader = (T_PPP_Header1*)(MainBuffer + MainBufferWr_Tx); // get address of the ppp header in the packet
PPPHeader->AddressField = 0xff; //
PPPHeader->ControlField = 0x03; //
PPPHeader->Protocol = htons(Protocol); //
MainBufferWr_Tx += sizeof(T_PPP_Header1); // update index
}
int PPP_AddCodeHeader(u8 Code)
{ // add the code header into the PPP packet
CodeHeader = (T_CodeHeader*)(MainBuffer + MainBufferWr_Tx); // get address of the code header in the packet
CodeHeader->Code = Code; // code
CodeHeader->ID = PPP.OurID; // ID
CodeHeader->Len = sizeof(T_CodeHeader); // length - update this as data is added to the packet
MainBufferWr_Tx += sizeof(T_CodeHeader); // update index
return CodeHeader->Len; // size of data we have added
}
void PPP_Add8(u8 b)
{ // add a byte into the PPP packet
MainBuffer[MainBufferWr_Tx++] = b; // 8-bit
CodeHeader->Len++; // update length
}
void PPP_Add16(u16 w)
{ // add a 16-bit value into the PPP packet
*(u16*)(MainBuffer + MainBufferWr_Tx) = htons(w); // 16-bit
MainBufferWr_Tx += 2; // update index
CodeHeader->Len += 2; // update length
}
void PPP_Add32(u32 dw)
{ // add a 32-bit value into the PPP packet
*(u32*)(MainBuffer + MainBufferWr_Tx) = htonl(dw); // 32-bit
MainBufferWr_Tx += 4; // update index
CodeHeader->Len += 4; // update length
}
int PPP_AddText(char *s)
{ // add text into the PPP packet
u16 i = (u16)strlen(s); // length of text
MainBuffer[MainBufferWr_Tx++] = (char)i; // length
strcpy((char*)MainBuffer + MainBufferWr_Tx, s); // text
MainBufferWr_Tx += i; // update index
CodeHeader->Len += 1 + i; // update length
return 1 + i; // size of data we have added
}
int PPP_Add_IPCP_Option(u8 Code)
{ // add an IP option into the PPP packet
u32 ip;
if (Code == 3) ip = PPP.OUR_IP.ip32; // point to our ip
else //
if (Code == 129) ip = PPP.DNS1_IP.ip32; // point to primary dns ip
else //
if (Code == 131) ip = PPP.DNS2_IP.ip32; // point to secondary dns ip
else //
return 0; //
//
PPP_Add8(Code); // type
PPP_Add8(6); // length
PPP_Add32(ntohl(ip)); // ip address
//
return 6; // size of option we have added
}
int PPP_AddACCM(u32 ACCM)
{ // add an ACCM option into the packet
PPP_Add8(LCP_ACCM); // type
PPP_Add8(6); // length
PPP_Add32(ACCM); // data
return 6; // size of option we have added
}
int PPP_AddMN(u32 MN)
{ // add a magic number option into the packet
PPP_Add8(LCP_MN); // type
PPP_Add8(6); // length
PPP_Add32(MN); // data
return 6; // size of option we have added
}
int PPP_AddMRU(u16 MRU)
{ // add an MRU option into the packet
PPP_Add8(LCP_MRU); // type
PPP_Add8(4); // length
PPP_Add16(MRU); // data
return 4; // size of option we have added
}
int PPP_AddPAP(void)
{
PPP_Add8(LCP_AP); // type
PPP_Add8(4); // length
PPP_Add16(PPP_PAP); // the auth protocol we can do
return 4; // size of option we have added
}
//****************************************************************************
bool PPP_SendEchoRequest(void)
{ // Send an LCP Echo request packet
u16 w;
PPP_StartPacket(PPP_LCP); //
PPP_AddCodeHeader(PPP_EREQ); //
PPP_Add32(PPP.TxMN); // magic number
//
CodeHeader->Len = htons(CodeHeader->Len); // correct byte order
//
u16_Put(&PPP.SendTick, 0); // reset the send retry timer
PPP.Retries++; // update the send retry counter
//
w = MainBufferWr_Tx; //
//
if (!PPP_SendPacket(true)) return false; // send the packet
//
#ifdef Debug
PPP_DisplayPacket(true, w); //
#endif
return true; //
}
bool PPP_SendIPRequest(void)
{ // Send a IPCP packet requesting the ip's (our's and the dns ip's)
u16 w;
PPP_StartPacket(PPP_IPCP); //
PPP_AddCodeHeader(PPP_CREQ); //
//
if (PPP.OUR_IP.ip32 != 0xffffffff) PPP_Add_IPCP_Option(3); // add our ip to the packet
if (PPP.DNS1_IP.ip32 != 0xffffffff) PPP_Add_IPCP_Option(129); // add the primary DNS ip
if (PPP.DNS2_IP.ip32 != 0xffffffff) PPP_Add_IPCP_Option(131); // add the secondary DNS ip
//
CodeHeader->Len = htons(CodeHeader->Len); // correct byte order
//
u16_Put(&PPP.SendTick, 0); // reset the send retry timer
PPP.Retries++; // update the send retry counter
//
w = MainBufferWr_Tx; // remember how many bytes their are
//
if (!PPP_SendPacket(false)) return false; // send the packet
//
#ifdef Debug
PPP_DisplayPacket(true, w); //
#endif
return true; //
}
bool PPP_SendPap(void)
{ // Send an LCP PAP login packet
u16 w;
PPP_StartPacket(PPP_PAP); //
PPP_AddCodeHeader(PPP_CREQ); //
PPP_AddText(PPP.Username); //
PPP_AddText(PPP.Password); //
//
CodeHeader->Len = htons(CodeHeader->Len); // correct byte order
//
u16_Put(&PPP.SendTick, 0); // reset the send retry timer
PPP.Retries++; // update the send retry counter
//
w = MainBufferWr_Tx; // remember how many bytes their are
//
if (!PPP_SendPacket(false)) return false; // send the packet
#ifdef Debug
PPP_DisplayPacket(true, w); //
#endif
return true; //
}
bool PPP_SendTermRequest(void)
{ // Send an LCP Terminate Request packet
u16 w;
PPP_StartPacket(PPP_LCP); //
PPP_AddCodeHeader(PPP_TREQ); //
//
u16_Put(&PPP.SendTick, 0); // reset the send retry timer
PPP.Retries++; // update the send retry counter
//
CodeHeader->Len = htons(CodeHeader->Len); // correct byte order
//
w = MainBufferWr_Tx; // remember how many bytes their are
//
if (!PPP_SendPacket(true)) return false; // send the packet
#ifdef Debug
PPP_DisplayPacket(true, w); //
#endif
return true; //
}
bool PPP_SendConfigRequest(void)
{
u16 w;
// *****************
// PPP into a windows server
#ifdef WindowsPPP
if (PPP.Stage == PPPS_Start)
{ // this is needed to log onto a windows PPP server
if (!SendModemRStr(PPP_WindowsStr)) return false; //
//
if (!WatchdogCounter) WatchdogCounter++; // tell timer interrupt to reset the watchdog
//
u16_Put(&PPP.SendTick, 0); //
for (; u16_Get(&PPP.SendTick) < 500; ); // wait for 500ms
//
if (!WatchdogCounter) WatchdogCounter++; // tell timer interrupt to reset the watchdog
}
#endif
// *****************
// Send an LCP CREQ packet - requesting the desired PPP options
if (PPP.Stage != PPPS_LCP) PPP_Stage(PPPS_LCP); //
//
PPP.AcceptedOurLCPOptions = false; // will be true when they accept all our options
//
PPP_StartPacket(PPP_LCP); //
PPP_AddCodeHeader(PPP_CREQ); //
if (PPP.TxMRU) PPP_AddMRU(PPP.TxMRU); //
if (PPP.TxACCM != 0xffffffff) PPP_AddACCM(PPP.TxACCM); //
if (PPP.TxMN) PPP_AddMN(PPP.TxMN); //
//
CodeHeader->Len = htons(CodeHeader->Len); // correct byte order
//
u16_Put(&PPP.SendTick, 0); // reset the send retry timer
PPP.Retries++; // update the send retry counter
//
w = MainBufferWr_Tx; // purly for debugging
//
if (!PPP_SendPacket(true)) return false; // send the packet
//
#ifdef Debug
PPP_DisplayPacket(true, w); // purly for debugging
#endif
return true; //
}
// **************************************************************************
// Save the incoming byte into the packet buffer.
// return false if the packet did not complete, else return true
bool PPP_AddNewRxByte(u8 c)
{
int i;
u8 type, len;
u16 InformationIndex, w, w2, Len, Protocol;
u32 dw;
u32 *p;
bool MustByteStuff, Terminate;
CodeHeader = 0; //
MustByteStuff = true; //
Terminate = false; //
MainBufferWr_Tx = 0; // write index
//
PPP.RxBytes++; // update byte counter
u16_Put(&PPP.LastRxData, 0); // reset timer
// ***********************
// save the incoming data into the main buffer.
// this is where we detect packet start/stops and do any byte de-stuffing.
// we also update the fcs here - as each byte comes in
if (c != PPP_Flag)
{ // packet data
if (MainBufferWr_Rx < 0) return false; // still waiting for the start of a packet
//
if (MainBufferWr_Rx >= sizeof(MainBuffer)) //
{ // buffer overflow - drop packet and wait for next one
MainBufferWr_Rx = -1; // wait for start of packet (PPP Flag)
return false; //
} //
//
if (c == PPP_EscapeFlag) //
{ // start de-stuffing
PPP.RxStuff = true; //
return false; //
} //
//
if (PPP.RxStuff) //
{ // previous byte was an Escape flag byte (byte stuffing)
PPP.RxStuff = false; //
c ^= PPP_Stuff; // recover the byte from it's stuffing
} //
//
if ((!MainBufferWr_Rx) && (c != 0xff)) return false; // this isn't really needed but every little helps
//
MainBuffer[MainBufferWr_Rx++] = c; // save the new byte into our PPP buffer
//
if (MainBufferWr_Rx >= 3) //
{ //
c = (u8)MainBuffer[MainBufferWr_Rx - 3]; // get byte from 3 bytes ago - to avoid pulling the fcs in
PPP.RxFCS = UpdateFCS_16(PPP.RxFCS, c); // update the fcs
} //
//
return false; //
} //
//
if (MainBufferWr_Rx < 6) goto ppp_end1; // not enough bytes to the ppp packet - need at least 6 bytes - drop the packet
//
PPP.RxFCS = ~PPP.RxFCS; // finalize the fcs
//
type = MainBuffer[--MainBufferWr_Rx]; //
w = (u16)type; // get fcs from packet
w <<= 8; // LS-Byte 1st
type = MainBuffer[--MainBufferWr_Rx]; //
w |= (u16)type; // get fcs from packet
//
if (PPP.RxFCS != w) // same as our calculated fcs ?
{ // nope
#ifdef Debug
SendDebugStr("\n "); //
SendDebugDataDump(MainBuffer, MainBufferWr_Rx + 2); //
sprintf((char*)ScratchPad, "\nFCS Error ... Len:%u OurFCS:%04X TheirFCS:%04X\n", 2 + MainBufferWr_Rx, PPP.RxFCS, w);
SendDebugStr((char*)ScratchPad);
#endif
goto ppp_end1; // fcs error - drop the packet
}
// *********************************************
// w00t, valid PPP packet !! ... process it
#ifdef Debug
PPP_DisplayPacket(false, MainBufferWr_Rx); // display the ppp packet on the console
#endif
MainBufferRd_Rx = 0; // reset read index
//
PPPHeader = (T_PPP_Header1*)(MainBuffer + MainBufferRd_Rx); // point to the PPP header
if (PPPHeader->AddressField != 0xff) goto ppp_end1; // bah
if (PPPHeader->ControlField != 0x03) goto ppp_end1; // moo
MainBufferRd_Rx += sizeof(T_PPP_Header1); // update read index
//
InformationIndex = MainBufferRd_Rx; // remember the current index
//
Protocol = ntohs(PPPHeader->Protocol); // fix byte order - to make things easier
// ***********************
// send a protocol reject packet back if the protocol is unknown to us
if ((Protocol != PPP_LCP) && //
(Protocol != PPP_PAP) && //
(Protocol != PPP_IPCP) && //
(Protocol != PPP_IP)) goto ppp_Unknown; // unknown protocol
// ***********************
// Internet Protocol (IP)
if (Protocol == PPP_IP)
{
if ((PPP.Stage != PPPS_IP) && (PPP.Stage != PPPS_Disc)) goto ppp_end1; // ignore it, we aint PPP'ed online yet
//
if (u32_Get(&PPP.LCP_Echo_Timer) < PPP_LCP_Echo_RetryTime) u32_Put(&PPP.LCP_Echo_Timer, 0); // don't think theirs a need to do echo tests while we still seem to be getting packets
//
MustByteStuff = false; //
IP_dec(); // pass the packet onto the IP layer
//
goto ppp_end1; //
}
// ****************
CodeHeader = (T_CodeHeader *)(MainBuffer + MainBufferRd_Rx); // point to the code header
MainBufferRd_Rx += sizeof(T_CodeHeader); // update read index
Len = sizeof(T_CodeHeader); // Len will be used if we need to send a packet back
// ****************
// Link Configure Protocol (LCP)
if (Protocol == PPP_LCP)
{
// *******************************************************
// terminate request
if (CodeHeader->Code == PPP_TREQ) //
{ //
CodeHeader->Code = PPP_TACK; // turn the rx'ed packet into an ACK
MainBufferWr_Tx = MainBufferWr_Rx; // send the whole thing back
//
Terminate = true; // tell the bit at the end of this function to close the link
goto ppp_end1; //
} //
// *******************************************************
// terminate ack
if (CodeHeader->Code == PPP_TACK) //
{ //
Terminate = true; // tell the bit at the end of this function to close the link
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -