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

📄 ppp.c

📁 ppp拨号程序源代码采用atmel芯片c语言编
💻 C
📖 第 1 页 / 共 4 页
字号:
	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 + -