📄 ppp.c
字号:
}
/***********************************************************************
Function : public PPPSendPAPPacket
Parameters : Action: LCP_REQ, LCP_REJ, LCP_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 ((BYTE *)user, &OutBuffer [9], strlen (user));
OutBuffer [9 + strlen (user)] = strlen (password);
Move ((BYTE *)password, &OutBuffer [10 + strlen (user)], strlen (password));
ProcPPPSend ((BYTE *)OutBuffer, OutBuffer[7] + 6);
}
/***********************************************************************
* 如果ISP发出了分配给本机IP地址的NAK协商包后,DTE端将此IP地址来请求,但却再也没收到
* ISP的IP地址ACK包,这时候将无法确定是哪个包丢掉,只有重新向ISP申请IP地址
***********************************************************************/
void SendIPCPReqIPAddr() {
static TMO tm=0;
if (tm==0) {
// 此函数第一次运行时,需要设好一个timer初始值
mstimeout(&tm,0);
return;
}
else {
if ( !mstimeout(&tm,2000) )
return;
}
// 这里如果需要申请IP地址,那么需要每隔一段时间周期性地去
// 请求,直到申请IP地址成功.这里设为2秒钟
// 我们自己的IP地址还没取到,所以要继续Request
OutBuffer[0] = 0xFF;
OutBuffer[1] = 0x03;
OutBuffer[2] = 0x80;
OutBuffer[3] = 0x21;
OutBuffer[4] = LCP_REQ; // Request command
OutBuffer[5] = PPP_PacketID++; // OutBuffer [5] + 1; // Packet ID = ID + 1
OutBuffer[6] = 0x00; // 长度字段,len=10
OutBuffer[7] = 0x0A;
OutBuffer[8] = 0x03; // Option 3
OutBuffer[9] = 0x06;
OutBuffer[10] = 0; // IP address is set to 0 so ISP server
OutBuffer[11] = 0; // can assign one to us
OutBuffer[12] = 0;
OutBuffer[13] = 0;
OutBuffer[14] = 0; // CRC 字段,暂设为零
OutBuffer[15] = 0;
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, int 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 ((BYTE *)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 : IPCompare
Parameters : Ip: A pointer to a IP address to compare
Date : November 2000
Desc : Compares an IP address to the default IP address defined
in this module
***********************************************************************/
BYTE IPCompare (BYTE *IPOne) {
if (IPOne [0] != EXT_IP_BYTE1) return (BYTE)0x00;
if (IPOne [1] != EXT_IP_BYTE2) return (BYTE)0x00;
if (IPOne [2] != EXT_IP_BYTE3) return (BYTE)0x00;
if (IPOne [3] != EXT_IP_BYTE4) return (BYTE)0x00;
return (BYTE) 0x01;
}
BOOL PPPLinkStatus() {
if ( (PPPStatus & LinkOn) )
return TRUE;
else
return FALSE;
}
/***********************************************************************
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.
***********************************************************************/
#define PK_TCP 0x06
#define PK_UDP 0x11
#define PK_ICMP 0x01
void PPPEntry (void) {
WORD PacketType;
WORD Checksum;
BYTE ck1,ck2;
if (PPPStatus & IsFrame) {
if ( !(PPPStatus & LinkOn) ) {
// PPP建立后验证收到包的FCS是否正确
// 在ppp链路没有建立以前,PPP包需要校验,PPP链路建立后,传送的包都是
// IP数据了,数据的正确性通过后面的检测手段来保证
// ppp链路建立以后,协议发生了变化,InBuffer[7]中不再存放的是长度值
// 所以FCS校验不能混在一起
// 协商阶段协议:
// 0xFF 0x03 Proto(2) Code(1) ID(1) Len(2) OPTIONs(N) FCS(2)
// PPP建立后协议:
// 0xFF 0x03 Proto(2) Data... FCS(2)
Checksum = PPPGetChecksum (InBuffer, InBuffer[7] + 4);
ck1 = Checksum & 0xFF;
ck2 = (Checksum >> 8) & 0xFF;
if (InBuffer[InBuffer[7]+4]!=ck1 || InBuffer[InBuffer[7]+5]!=ck2) {
// 验证不能通过
PPPStatus &= ~IsFrame;
PPPStatus |= ReSync;
return;
}
}
#ifdef PPP_PACKET_ANYSIS
if (BufAnysisIndex<MAX_PPP_BUF_ANYSIS_NUM) {
memcpy((UB *)BufAnysis[BufAnysisIndex],InBuffer,InBuffer[7] + 12); // packet save
BufAnysisFlag[BufAnysisIndex++]=1; // receive packet
}
#endif
#ifdef FOR_LITTLE_ENDIAN
PacketType=((WORD)InBuffer[2] << 8) | InBuffer[3] ;
#endif
switch (PacketType) {
case LCP_PACKET:
HandleLCPOptions ();
break;
case PAP_PACKET:
if (InBuffer [4] == 0x02) {
PPPStatus |= PAP_FIN; // Authentication OK
}
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
break;
}
else {
/*
switch (InBuffer [13]) {
case PK_UDP:
//UDP_Handler ((UDPDatagram *)&InBuffer[16]);
break;
case PK_TCP:
break;
case PK_ICMP:
//IcmpHandler ((IPDatagram *)&InBuffer[4]);
break;
default:
break;
}
*/
#ifdef PPP_IP_ANYSIS
if (InBuffer[16]==61 &&
InBuffer[17]==141 &&
InBuffer[18]==237 &&
InBuffer[19]==100 )
{
if (BufIPAnysisIndex<MAX_PPP_IP_NUM)
memcpy(BufIpAnysis[BufIPAnysisIndex++],\
(BYTE *)&InBuffer[4],sizeof(InBuffer)-4);
}
#endif
// 将收到的数据copy到公共接收区,准备集中处理
// 这里去掉ppp包头部数据,也就是说LinkRxBuf的起始值就是
// IP包头
memcpy(LinkRxBuf,(BYTE *)&InBuffer[4],sizeof(InBuffer)-4);
pLinkRxBuf=LinkRxBuf;
//static BYTE pktcnt=0;
//if (memchr((UB *)LinkRxBuf,'G',70)) {
// pktcnt=0;
//}
// 标识此包是通过PPP传过来
RxBufType=FROM_PPP;
bPPPRcvOneFrame=1;
break;
}
default:
// Cannot handle this type of packet
RejectProtocol (InBuffer);
break;
};
PPPStatus &= ~IsFrame;
PPPStatus |= ReSync;
}
else if ((PPPStatus & PAP_FIN) && !(PPPStatus & LinkOn)) {
// 认证已经通过,此时ppp进入IPCP协议阶段,但IP地址还没有得到
SendIPCPReqIPAddr();
}
}
//***********************************************************************
extern UH ModemStatus;
void PPPTask() {
if (ModemStatus & MODEM_ONLINE) { // 如果modem在线,才能处理ppp协议层
pppRcv();
PPPEntry();
}
}
//***********************************************************************
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -