462 lines
12 KiB
C++
462 lines
12 KiB
C++
|
/*++
|
||
|
|
||
|
Copyright (c) 2000 Microsoft Corporation
|
||
|
|
||
|
smaction.cpp
|
||
|
|
||
|
Abstract:
|
||
|
|
||
|
Handle actions that occur during state transitions.
|
||
|
|
||
|
Revision History:
|
||
|
|
||
|
07-14-00 vadimg created
|
||
|
|
||
|
--*/
|
||
|
|
||
|
#include "precomp.h"
|
||
|
|
||
|
/***************************************************************************\
|
||
|
* FsmSendConfigReq
|
||
|
*
|
||
|
\***************************************************************************/
|
||
|
|
||
|
BOOL FsmSendConfigReq(DWORD CpIndex)
|
||
|
{
|
||
|
DWORD dwRetCode;
|
||
|
PPP_PACKET *pSendPacket = GetSendPacket();
|
||
|
PPP_CONFIG *pSendConfig = (PPP_CONFIG*)pSendPacket->Data;
|
||
|
DWORD dwLength;
|
||
|
|
||
|
dwRetCode = (gCpTable[CpIndex].CP_MakeConfigRequest)(pSendConfig,
|
||
|
LCP_DEFAULT_MRU - PPP_PACKET_HDR_LEN);
|
||
|
|
||
|
if (dwRetCode != NO_ERROR) {
|
||
|
gInfo.dwError = dwRetCode;
|
||
|
FsmClose(CpIndex);
|
||
|
return FALSE;
|
||
|
}
|
||
|
|
||
|
HostToWireFormat16((WORD)gCpTable[CpIndex].Protocol,
|
||
|
(PBYTE)pSendPacket->Protocol);
|
||
|
|
||
|
pSendConfig->Code = CONFIG_REQ;
|
||
|
|
||
|
//
|
||
|
// If we are resending a configure request because of a timeout, we do not
|
||
|
// use the id of the previous configure request, instead we get a new Id.
|
||
|
// Id we do not, then the wrong Config-Req's and Config-Acks may be matched
|
||
|
// up and we start getting crossed connections.
|
||
|
//
|
||
|
|
||
|
pSendConfig->Id = GetId();
|
||
|
|
||
|
dwLength = WireToHostFormat16(pSendConfig->Length);
|
||
|
|
||
|
SendFrame(dwLength + PPP_PACKET_HDR_LEN);
|
||
|
|
||
|
gInfo.LastId = pSendConfig->Id;
|
||
|
|
||
|
SetTimeout();
|
||
|
|
||
|
return TRUE;
|
||
|
}
|
||
|
|
||
|
/***************************************************************************\
|
||
|
* FsmSendTermReq
|
||
|
*
|
||
|
\***************************************************************************/
|
||
|
|
||
|
BOOL FsmSendTermReq(DWORD CpIndex)
|
||
|
{
|
||
|
PPP_PACKET *pSendPacket = GetSendPacket();
|
||
|
PPP_CONFIG *pSendConfig = (PPP_CONFIG*)pSendPacket->Data;
|
||
|
|
||
|
HostToWireFormat16((WORD)gCpTable[CpIndex].Protocol,
|
||
|
(PBYTE)pSendPacket->Protocol);
|
||
|
|
||
|
pSendConfig->Code = TERM_REQ;
|
||
|
pSendConfig->Id = GetId();
|
||
|
|
||
|
HostToWireFormat16((WORD)((PPP_CONFIG_HDR_LEN)+(sizeof(DWORD)*3)),
|
||
|
(PBYTE)pSendConfig->Length);
|
||
|
|
||
|
HostToWireFormat32(gLcp.Local.Work.MagicNumber, (PBYTE)pSendConfig->Data);
|
||
|
HostToWireFormat32(777, (PBYTE)(pSendConfig->Data+4));
|
||
|
HostToWireFormat32(gInfo.dwError, (PBYTE)(pSendConfig->Data+8));
|
||
|
|
||
|
SendFrame(PPP_PACKET_HDR_LEN + PPP_CONFIG_HDR_LEN + sizeof(DWORD) * 3);
|
||
|
|
||
|
gInfo.LastId = pSendConfig->Id;
|
||
|
return TRUE;
|
||
|
}
|
||
|
|
||
|
/***************************************************************************\
|
||
|
* FsmSendTermAck
|
||
|
*
|
||
|
\***************************************************************************/
|
||
|
|
||
|
BOOL FsmSendTermAck(DWORD CpIndex, PPP_CONFIG *pRecvConfig)
|
||
|
{
|
||
|
PPP_PACKET *pSendPacket = GetSendPacket();
|
||
|
PPP_CONFIG *pSendConfig = (PPP_CONFIG*)pSendPacket->Data;
|
||
|
DWORD dwLength;
|
||
|
|
||
|
dwLength = PPP_PACKET_HDR_LEN + WireToHostFormat16(pRecvConfig->Length);
|
||
|
if (dwLength > LCP_DEFAULT_MRU) {
|
||
|
dwLength = LCP_DEFAULT_MRU;
|
||
|
}
|
||
|
|
||
|
HostToWireFormat16((WORD)gCpTable[CpIndex].Protocol,
|
||
|
(PBYTE)pSendPacket->Protocol);
|
||
|
|
||
|
pSendConfig->Code = TERM_ACK;
|
||
|
pSendConfig->Id = pRecvConfig->Id;
|
||
|
|
||
|
HostToWireFormat16((WORD)(dwLength - PPP_PACKET_HDR_LEN),
|
||
|
(PBYTE)pSendConfig->Length);
|
||
|
|
||
|
CopyMemory(pSendConfig->Data, pRecvConfig->Data,
|
||
|
dwLength - PPP_CONFIG_HDR_LEN - PPP_PACKET_HDR_LEN);
|
||
|
|
||
|
SendFrame(dwLength);
|
||
|
|
||
|
return TRUE;
|
||
|
}
|
||
|
|
||
|
/***************************************************************************\
|
||
|
* FsmSendConfigResult
|
||
|
*
|
||
|
\***************************************************************************/
|
||
|
|
||
|
BOOL FsmSendConfigResult(DWORD CpIndex, PPP_CONFIG *pRecvConfig, BOOL *pfAcked)
|
||
|
{
|
||
|
PPP_PACKET *pSendPacket = GetSendPacket();
|
||
|
PPP_CONFIG *pSendConfig = (PPP_CONFIG*)pSendPacket->Data;
|
||
|
DWORD dwLength;
|
||
|
DWORD dwRetCode;
|
||
|
|
||
|
*pfAcked = FALSE;
|
||
|
|
||
|
ZeroMemory(pSendConfig, 30);
|
||
|
|
||
|
pSendConfig->Id = pRecvConfig->Id;
|
||
|
|
||
|
dwRetCode = (gCpTable[CpIndex].CP_MakeConfigResult)(pRecvConfig, pSendConfig,
|
||
|
LCP_DEFAULT_MRU - PPP_PACKET_HDR_LEN, (gInfo.NakRetryCount == 0));
|
||
|
|
||
|
if (dwRetCode == ERROR_PPP_INVALID_PACKET) {
|
||
|
|
||
|
return FALSE;
|
||
|
|
||
|
} else if (dwRetCode != NO_ERROR) {
|
||
|
|
||
|
gInfo.dwError = dwRetCode;
|
||
|
FsmClose(CpIndex);
|
||
|
return FALSE;
|
||
|
}
|
||
|
|
||
|
switch (pSendConfig->Code) {
|
||
|
case CONFIG_ACK:
|
||
|
*pfAcked = TRUE;
|
||
|
break;
|
||
|
|
||
|
case CONFIG_NAK:
|
||
|
if (gInfo.NakRetryCount > 0) {
|
||
|
gInfo.NakRetryCount--;
|
||
|
} else {
|
||
|
|
||
|
gInfo.dwError = ERROR_PPP_NOT_CONVERGING;
|
||
|
FsmClose(CP_LCP);
|
||
|
return FALSE;
|
||
|
}
|
||
|
break;
|
||
|
|
||
|
case CONFIG_REJ:
|
||
|
if (gInfo.RejRetryCount > 0) {
|
||
|
gInfo.RejRetryCount--;
|
||
|
} else {
|
||
|
|
||
|
gInfo.dwError = ERROR_PPP_NOT_CONVERGING;
|
||
|
FsmClose(CP_LCP);
|
||
|
return FALSE;
|
||
|
}
|
||
|
break;
|
||
|
}
|
||
|
|
||
|
HostToWireFormat16((WORD)gCpTable[CpIndex].Protocol,
|
||
|
(PBYTE)pSendPacket->Protocol);
|
||
|
|
||
|
pSendConfig->Id = pRecvConfig->Id;
|
||
|
dwLength = WireToHostFormat16(pSendConfig->Length);
|
||
|
|
||
|
SendFrame(dwLength + PPP_PACKET_HDR_LEN);
|
||
|
|
||
|
return TRUE;
|
||
|
}
|
||
|
|
||
|
/***************************************************************************\
|
||
|
* FsmSendEchoReply
|
||
|
*
|
||
|
\***************************************************************************/
|
||
|
|
||
|
BOOL FsmSendEchoReply(DWORD CpIndex, PPP_CONFIG *pRecvConfig)
|
||
|
{
|
||
|
PPP_PACKET *pSendPacket = GetSendPacket();
|
||
|
PPP_CONFIG *pSendConfig = (PPP_CONFIG*)pSendPacket->Data;
|
||
|
DWORD dwLength;
|
||
|
|
||
|
dwLength = PPP_PACKET_HDR_LEN + WireToHostFormat16(pRecvConfig->Length);
|
||
|
if (dwLength > LCP_DEFAULT_MRU) {
|
||
|
dwLength = LCP_DEFAULT_MRU;
|
||
|
}
|
||
|
|
||
|
if (dwLength < PPP_PACKET_HDR_LEN + PPP_CONFIG_HDR_LEN + 4) {
|
||
|
return FALSE;
|
||
|
}
|
||
|
|
||
|
HostToWireFormat16((WORD)gCpTable[CpIndex].Protocol,
|
||
|
(PBYTE)pSendPacket->Protocol);
|
||
|
|
||
|
pSendConfig->Code = ECHO_REPLY;
|
||
|
pSendConfig->Id = pRecvConfig->Id;
|
||
|
|
||
|
HostToWireFormat16((WORD)(dwLength - PPP_PACKET_HDR_LEN),
|
||
|
(PBYTE)pSendConfig->Length);
|
||
|
|
||
|
HostToWireFormat32(gLcp.Local.Work.MagicNumber, (PBYTE)pSendConfig->Data);
|
||
|
|
||
|
CopyMemory(pSendConfig->Data + 4, pRecvConfig->Data + 4,
|
||
|
dwLength - PPP_CONFIG_HDR_LEN - PPP_PACKET_HDR_LEN - 4);
|
||
|
|
||
|
SendFrame(dwLength);
|
||
|
|
||
|
return TRUE;
|
||
|
}
|
||
|
|
||
|
/***************************************************************************\
|
||
|
* FsmSendCodeReject
|
||
|
*
|
||
|
\***************************************************************************/
|
||
|
|
||
|
BOOL FsmSendCodeReject(DWORD CpIndex, PPP_CONFIG *pRecvConfig)
|
||
|
{
|
||
|
PPP_PACKET *pSendPacket = GetSendPacket();
|
||
|
PPP_CONFIG *pSendConfig = (PPP_CONFIG*)pSendPacket->Data;
|
||
|
DWORD dwLength;
|
||
|
|
||
|
dwLength = PPP_PACKET_HDR_LEN + PPP_CONFIG_HDR_LEN +
|
||
|
WireToHostFormat16(pRecvConfig->Length);
|
||
|
|
||
|
if (dwLength > LCP_DEFAULT_MRU) {
|
||
|
dwLength = LCP_DEFAULT_MRU;
|
||
|
}
|
||
|
|
||
|
HostToWireFormat16((WORD)gCpTable[CpIndex].Protocol,
|
||
|
(PBYTE)pSendPacket->Protocol);
|
||
|
|
||
|
pSendConfig->Code = CODE_REJ;
|
||
|
pSendConfig->Id = GetId();
|
||
|
|
||
|
HostToWireFormat16((WORD)(dwLength - PPP_PACKET_HDR_LEN),
|
||
|
(PBYTE)pSendConfig->Length);
|
||
|
|
||
|
CopyMemory( pSendConfig->Data,
|
||
|
pRecvConfig,
|
||
|
dwLength - PPP_CONFIG_HDR_LEN - PPP_PACKET_HDR_LEN );
|
||
|
|
||
|
SendFrame(dwLength);
|
||
|
|
||
|
return TRUE;
|
||
|
}
|
||
|
|
||
|
/***************************************************************************\
|
||
|
* FsmSendProtocolRej
|
||
|
*
|
||
|
\***************************************************************************/
|
||
|
|
||
|
BOOL FsmSendProtocolRej(PPP_PACKET *pPacket, DWORD dwPacketLength)
|
||
|
{
|
||
|
PPP_PACKET *pSendPacket = GetSendPacket();
|
||
|
PPP_CONFIG *pSendConfig = (PPP_CONFIG*)pSendPacket->Data;
|
||
|
PPP_CONFIG *pRecvConfig = (PPP_CONFIG*)pPacket->Data;
|
||
|
DWORD dwLength;
|
||
|
|
||
|
// If LCP isn't in the opened state we can't send a protocol reject packet
|
||
|
if (!IsLcpOpened()) {
|
||
|
return ERROR_UNKNOWN;
|
||
|
}
|
||
|
|
||
|
dwLength = PPP_PACKET_HDR_LEN + PPP_CONFIG_HDR_LEN + dwPacketLength;
|
||
|
|
||
|
if (dwLength > LCP_DEFAULT_MRU) {
|
||
|
dwLength = LCP_DEFAULT_MRU;
|
||
|
}
|
||
|
|
||
|
HostToWireFormat16((WORD)gCpTable[CP_LCP].Protocol,
|
||
|
(PBYTE)pSendPacket->Protocol);
|
||
|
|
||
|
pSendConfig->Code = PROT_REJ;
|
||
|
pSendConfig->Id = GetId();
|
||
|
|
||
|
HostToWireFormat16((WORD)(dwLength - PPP_PACKET_HDR_LEN),
|
||
|
(PBYTE)pSendConfig->Length);
|
||
|
|
||
|
CopyMemory(pSendConfig->Data, pPacket,
|
||
|
dwLength - PPP_CONFIG_HDR_LEN - PPP_PACKET_HDR_LEN);
|
||
|
|
||
|
SendFrame(dwLength);
|
||
|
|
||
|
return TRUE;
|
||
|
}
|
||
|
|
||
|
/***************************************************************************\
|
||
|
* FsmInit
|
||
|
*
|
||
|
\***************************************************************************/
|
||
|
|
||
|
BOOL FsmInit(DWORD CpIndex)
|
||
|
{
|
||
|
DWORD dwRetCode;
|
||
|
|
||
|
gInfo.dwError = NO_ERROR;
|
||
|
gInfo.State = FSM_INITIAL;
|
||
|
|
||
|
if (!FsmReset(CpIndex)) {
|
||
|
return FALSE;
|
||
|
}
|
||
|
|
||
|
dwRetCode = gCpTable[CpIndex].CP_Begin();
|
||
|
if (dwRetCode != NO_ERROR) {
|
||
|
gInfo.dwError = dwRetCode;
|
||
|
return FALSE;
|
||
|
}
|
||
|
|
||
|
return TRUE;
|
||
|
}
|
||
|
|
||
|
/***************************************************************************\
|
||
|
* FsmReset
|
||
|
*
|
||
|
\***************************************************************************/
|
||
|
|
||
|
BOOL FsmReset(DWORD CpIndex)
|
||
|
{
|
||
|
InitRestartCounters();
|
||
|
|
||
|
gInfo.NakRetryCount = PPP_MAX_FAILURE;
|
||
|
gInfo.RejRetryCount = PPP_MAX_FAILURE;
|
||
|
|
||
|
gInfo.LastId = 0;
|
||
|
return TRUE;
|
||
|
}
|
||
|
|
||
|
/***************************************************************************\
|
||
|
* FsmThisLayerUp
|
||
|
*
|
||
|
\***************************************************************************/
|
||
|
|
||
|
BOOL FsmThisLayerUp(DWORD CpIndex)
|
||
|
{
|
||
|
DWORD dwRetCode;
|
||
|
|
||
|
DbgPrint("LcpThisLayerUp %4X\n", gCpTable[CpIndex].Protocol);
|
||
|
|
||
|
if (gCpTable[CpIndex].CP_ThisLayerUp != NULL) {
|
||
|
|
||
|
dwRetCode = gCpTable[CpIndex].CP_ThisLayerUp();
|
||
|
if (dwRetCode != NO_ERROR) {
|
||
|
gInfo.dwError = dwRetCode;
|
||
|
FsmClose(CpIndex);
|
||
|
return FALSE;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
switch (gInfo.Phase) {
|
||
|
case PPP_LCP:
|
||
|
gInfo.Phase = PPP_AP;
|
||
|
CpIndex = GetCpIndexFromProtocol(gLcp.Remote.Work.AP);
|
||
|
ApStart(CpIndex);
|
||
|
break;
|
||
|
|
||
|
case PPP_AP:
|
||
|
gInfo.Phase = PPP_NCP;
|
||
|
CpIndex = CP_IPCP;
|
||
|
NcpStart(CpIndex);
|
||
|
break;
|
||
|
|
||
|
case PPP_NCP:
|
||
|
InitNet();
|
||
|
break;
|
||
|
}
|
||
|
|
||
|
return TRUE;
|
||
|
}
|
||
|
|
||
|
/***************************************************************************\
|
||
|
* FsmThisLayerDown
|
||
|
*
|
||
|
\***************************************************************************/
|
||
|
|
||
|
BOOL FsmThisLayerDown(DWORD CpIndex)
|
||
|
{
|
||
|
DWORD dwRetCode;
|
||
|
|
||
|
DbgPrint("LcpThisLayerDown %4X\n", gCpTable[CpIndex].Protocol);
|
||
|
|
||
|
if (gCpTable[CpIndex].CP_ThisLayerDown != NULL) {
|
||
|
dwRetCode = gCpTable[CpIndex].CP_ThisLayerDown();
|
||
|
if (dwRetCode != NO_ERROR) {
|
||
|
gInfo.dwError = dwRetCode;
|
||
|
FsmClose(CpIndex);
|
||
|
return FALSE;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
if (CpIndex == CP_LCP) {
|
||
|
// bring down all NCPs
|
||
|
// bring down AP
|
||
|
}
|
||
|
return TRUE;
|
||
|
}
|
||
|
|
||
|
/***************************************************************************\
|
||
|
* FsmThisLayerStarted
|
||
|
*
|
||
|
\***************************************************************************/
|
||
|
|
||
|
BOOL FsmThisLayerStarted(DWORD CpIndex)
|
||
|
{
|
||
|
DWORD dwRetCode;
|
||
|
|
||
|
if (gCpTable[CpIndex].CP_ThisLayerStarted != NULL) {
|
||
|
dwRetCode = gCpTable[CpIndex].CP_ThisLayerStarted();
|
||
|
if (dwRetCode != NO_ERROR) {
|
||
|
gInfo.dwError = dwRetCode;
|
||
|
FsmClose(CpIndex);
|
||
|
return FALSE;
|
||
|
}
|
||
|
}
|
||
|
return TRUE;
|
||
|
}
|
||
|
|
||
|
/***************************************************************************\
|
||
|
* FsmThisLayerFinished
|
||
|
*
|
||
|
\***************************************************************************/
|
||
|
|
||
|
BOOL FsmThisLayerFinished(DWORD CpIndex)
|
||
|
{
|
||
|
DWORD dwRetCode;
|
||
|
|
||
|
if (gCpTable[CpIndex].CP_ThisLayerFinished != NULL) {
|
||
|
dwRetCode = gCpTable[CpIndex].CP_ThisLayerFinished();
|
||
|
if (dwRetCode != NO_ERROR) {
|
||
|
gInfo.dwError = dwRetCode;
|
||
|
return FALSE;
|
||
|
}
|
||
|
}
|
||
|
return TRUE;
|
||
|
}
|
||
|
|