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

📄 ppp.c

📁 基于51的单片机的PPP协议实现
💻 C
📖 第 1 页 / 共 2 页
字号:
						OutBuffer [7] = OutBuffer [7] - Size;	// Set New Packet size
					}
					else {
						while (Size-- ) {			// Copy this option to the output buffer
							*dest++ = *ptr++;
						}
					}

				}
			} else

			//////////////////////////////////////////////////////////////////////
			/////// Server Request CHAP protocol, We reply with
			/////// a suggestion of the PAP protocol instead
			//////////////////////////////////////////////////////////////////////
			if ((InBuffer [8] == 0x03) && (InBuffer [10] == 0xC2)) {
				InBuffer [4] = NAK;					// NAK CHAP protocol
				InBuffer [10] = 0xC0;					// We suggest PAP instead
				ProcPPPSend (InBuffer, InBuffer[7]+6);			// Send the NAK reply
				return;
			} else

			//////////////////////////////////////////////////////////////////////
			/////// Server Request PAP protocol //////////
			/////// We Acknowledge this reply and then we start negotiating
			/////// the Async-Control-Char..., Here we send both packets!!!
			//////////////////////////////////////////////////////////////////////
				if ((InBuffer [8] == 0x03) && (InBuffer [10] == 0xC0)) {
					Move (InBuffer, OutBuffer, InBuffer[7]+6);
					OutBuffer[4] = ACK;

					ProcPPPSend ((BYTE *)OutBuffer, OutBuffer[7] + 6);

					OutBuffer[4] = REQ;
					OutBuffer[5] = OutBuffer [5] + 1;
					OutBuffer[7] = 0x0A;
					OutBuffer[8] = 0x02;
					OutBuffer[9] = 0x06;
					OutBuffer[10] = 0xFF;
					OutBuffer[11] = 0xFF;
					OutBuffer[12] = 0xFF;
					OutBuffer[13] = 0xFF;

			}
		ProcPPPSend ((BYTE *)OutBuffer, OutBuffer[7] + 6);
		break;

		//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
		case ACK:
			//////////////////////////////////////////////////////////////////////
			/////// Server Acknowledge Async Control //////////
			//////////////////////////////////////////////////////////////////////
			if (InBuffer [8] == 0x02) {
				SendPAPPacket (REQ, InBuffer[5] + 1, User, Password);
			}
		break;

		//++++++++++++++++++++++++++++++++++++++++++++++++++++
		case NAK:
		break;

		//++++++++++++++++++++++++++++++++++++++++++++++++++++
		case REJ:
		break;
		
		//++++++++++++++++++++++++++++++++++++++++++++++++++++
		case TERMINATE_ACK:			// Terminate ACK!
			PPPStatus &= ~LinkOn;
		break;

	}
	return;
}



/***********************************************************************
Function : 	protected HandleIPCPOptions

Parameters : 	None

Date : 		August 2000

Desc : 		State Machine that implement IPCP packet negotiation 
		
***********************************************************************/

static void HandleIPCPOptions (void) {
BYTE *dest = (BYTE *)&OutBuffer[8];
BYTE *ptr = (BYTE *)&InBuffer[8];
BYTE FrameSize;
BYTE Option;
BYTE Size;



	switch (InBuffer [4] ) {
		case REQ:
			if ((InBuffer [8] != 0x03) && (InBuffer [7] > 0x0A)) {
					OutBuffer [0] = 0xFF;		// Build a IPCP header 
					OutBuffer [1] = 0x03;
					OutBuffer [2] = 0x80;		// Set IPCP protocol field
					OutBuffer [3] = 0x21;
					OutBuffer [4] = REJ;		// This will be REJ packet for now
					OutBuffer [5] = InBuffer [5];
					FrameSize = InBuffer[7] - 4;
					///////// Ignore all but option #3 ///////
					while (FrameSize > 0) {
						Option = *ptr;
						Size = *(ptr + 1);

						FrameSize -= Size;

						if (Option == 3) {
							ptr += Size;
							OutBuffer [7] = InBuffer [7] - Size;	//Set New Packet size
						}
						else {
							while (Size-- ) {
								*dest++ = *ptr++;
							}
						}
					}
			}
			else {
					//// Acknowledge IP Address ////
					Move (InBuffer, OutBuffer, InBuffer[7]+6);
					OutBuffer [4] = ACK;


					ProcPPPSend ((BYTE *)OutBuffer, OutBuffer[7] + 6);


					//// Now Request IP address to complete 3-way handshake
          				OutBuffer [4] = REQ;			// Request command
					OutBuffer [5] = OutBuffer [5] + 1;	// Packet ID = ID + 1
					OutBuffer [10] = 0;			// IP address is set to 0 so ISP server 
					OutBuffer [11] = 0;			// can assing one to us
					OutBuffer [12] = 0;
					OutBuffer [13] = 0;

			}
			ProcPPPSend ((BYTE *)OutBuffer, OutBuffer[7] + 6);

		break;

		case ACK:
			if (InBuffer [8] == 3) {			// Reply of the only IPCP Request we can send
				IPAddress [0] = InBuffer [10];		// ISP assigned IP address
				IPAddress [1] = InBuffer [11];		
				IPAddress [2] = InBuffer [12];
				IPAddress [3] = InBuffer [13];
				
				PORTC = 0xFF;
				PPPStatus |= LinkOn;			// PPP Link is now up
			}
		break;

		case NAK:
			if ((InBuffer [8] == 0x03) && (InBuffer [7] <= 0x0A)) {
					/// Request IP Address ////
					Move (InBuffer, OutBuffer, InBuffer[7]+6);
					OutBuffer [4] = 0x01;

					ProcPPPSend ((BYTE *)OutBuffer, OutBuffer[7] + 6);
			}
		break;

		case REJ:
		break;
	}

}


/***********************************************************************
Function : 	public PPPSendPAPPacket 

Parameters : 	Action: 	REQ, REJ, NAK
		ID:		Sequence number of PPP packet
		user:		User name for login
		password:	Password in plain text

Date : 		September 2000

Desc : 		Formats a PAP packet on Output Buffer. This function
		supports the type field for future implementation of
		the PPP module in server mode.
***********************************************************************/

void SendPAPPacket (BYTE Action, BYTE ID, char* user, char* password) {
	OutBuffer [0] = 0xFF;
	OutBuffer [1] = 0x03;
	OutBuffer [2] = 0xC0;
	OutBuffer [3] = 0x23;
	OutBuffer [4] = Action;
	OutBuffer [5] = InBuffer [5] + 1;
	OutBuffer [6] = 0;
	OutBuffer [7] = strlen (user) + strlen (password) + 6;
	OutBuffer [8] = strlen (user);
	Move (user, &OutBuffer [9], strlen (user));
	OutBuffer [9 + strlen (user)] = strlen (password);
	Move (password, &OutBuffer [10 + strlen (user)], strlen (password));
	ProcPPPSend ((BYTE *)OutBuffer, OutBuffer[7] + 6);
}

/***********************************************************************
Function : 	Move

Parameters : 	src:	 	A pointer to the data to copy 
		dest:		A pointer to the destination location 
		numBYTEs:	Number of bytes to copy

Date : 		September 2000

Desc : 		Copies a block of numBYTEs bytes from src pointer 
		to dest pointer
***********************************************************************/
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 );
}




/***********************************************************************
Function : 	protected RejectProtocol  

Parameters : 	InBuffer -> A pointer to the buffer that has the PPP
		Packet to reject

Date : 		August 2000

Desc : 		Rejects the a PPP packet based on its Protocol field
		Stored on InBuffer
		
***********************************************************************/

static void RejectProtocol (BYTE *InBuffer) {

	OutBuffer [0] = 0xFF;
	OutBuffer [1] = 0x03;
	OutBuffer [2] = 0xC0;
	OutBuffer [3] = 0x21;
	OutBuffer [4] = 0x08;
	OutBuffer [5] = 20;
	OutBuffer [6] = 0;
	OutBuffer [7] = InBuffer[7] + 6;
	Move (&InBuffer[2], &OutBuffer[8], InBuffer [7] + 2);
	ProcPPPSend ((BYTE *)OutBuffer, OutBuffer[7] + 6);
}



/***********************************************************************
Function : 	protected PPPSendVoidLcp 

Parameters : 	None

Date : 		September 2000

Desc : 		Sends a void LCP packet with no options to the PPP Server.
		This will force the server to reply with his options to 
		negotiate. Some ISPs require scripts to stablish a connection thus
		a void LCP packet will try to force the server to negotiate PPP.  
***********************************************************************/

void PPPSendVoidLCP (void) {
WORD Checksum;

	Move (PPPData, OutBuffer, PPPData[7] + 6);
	ProcPPPSend ((BYTE *)OutBuffer, OutBuffer[7] + 6);
}


/***********************************************************************
Function : 	PPPTerminate

Parameters : 	None

Date : 		September 2000

Desc : 		Terminates a PPP link by sending a terminate LCP packet
***********************************************************************/
void PPPTerminate (void) {
   Move ((BYTE *)LCPTerminate, OutBuffer, 10);
   ProcPPPSend (OutBuffer, 10);
}


/***********************************************************************
Function : 	PPPEntry  

Parameters : 	None

Date : 		August 2000

Desc : 		PPP Module Entry, Applications should call PPPEntry 
		frequently in the main loop or in portions of the app 
		code.
***********************************************************************/

void PPPEntry (void) {
		if (PPPStatus & IsFrame) {
		switch (*(WORD *)(&InBuffer [2])) {

				case LCP_PACKET:	
					HandleLCPOptions ();
				break;

				case PAP_PACKET:
					if (InBuffer [4] == 0x02) {	// Authentication OK
						NoOperation;
                    			}
				break;

				case IPCP_PACKET:  			// IPCP Handler
					HandleIPCPOptions ();
				break;

				case IP_DATAGRAM:			// IP Data Handler 
					if (!IPCompare ((BYTE *)&InBuffer [20])) {
									// Misrouted datagram or broadcast message received 
						
					}
					else		
						switch (InBuffer [13]) {

							case UDP:
					                	UDP_Handler ((UDPDatagram *)&InBuffer[16]);							
							break;

							case TCP:
							break;
	
							case ICMP:
								IcmpHandler ((IPDatagram *)&InBuffer[4]);
							break;

							default:
							break;								
						}
				break;


				default:
					RejectProtocol (InBuffer);	// Cannot handle this type of packet 
				break;
			};
    
			PPPStatus &= ~IsFrame;
			PPPStatus |= ReSync;
		}

}

⌨️ 快捷键说明

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