290 lines
7.5 KiB
C++
290 lines
7.5 KiB
C++
|
/*++
|
||
|
|
||
|
Copyright (c) 2000 Microsoft Corporation
|
||
|
|
||
|
ncp.cpp
|
||
|
|
||
|
Abstract:
|
||
|
|
||
|
Network control protocol and IPCP implementation.
|
||
|
|
||
|
Revision History:
|
||
|
|
||
|
07-27-00 vadimg created
|
||
|
|
||
|
--*/
|
||
|
|
||
|
#include "precomp.h"
|
||
|
|
||
|
/***************************************************************************\
|
||
|
* NcpStart
|
||
|
*
|
||
|
\***************************************************************************/
|
||
|
|
||
|
BOOL NcpStart(DWORD CpIndex)
|
||
|
{
|
||
|
if (!FsmInit(CpIndex)) {
|
||
|
return FALSE;
|
||
|
}
|
||
|
|
||
|
FsmOpen(CpIndex);
|
||
|
FsmUp(CpIndex);
|
||
|
|
||
|
return TRUE;
|
||
|
}
|
||
|
|
||
|
/***************************************************************************\
|
||
|
* NcpReset
|
||
|
*
|
||
|
\***************************************************************************/
|
||
|
|
||
|
VOID NcpReset(VOID)
|
||
|
{
|
||
|
gIp.IpAddrRemote = 0;
|
||
|
gIp.IpAddrLocal = 0;
|
||
|
gIp.IpAddrDns = 0;
|
||
|
}
|
||
|
|
||
|
/***************************************************************************\
|
||
|
* AddIpAddressOption
|
||
|
*
|
||
|
\***************************************************************************/
|
||
|
|
||
|
VOID AddIpAddressOption(BYTE *pBuf, BYTE bOption, IPADDR ipaddr)
|
||
|
{
|
||
|
*pBuf++ = bOption;
|
||
|
*pBuf++ = IPADDRESSOPTIONLEN;
|
||
|
*((IPADDR*)pBuf) = ipaddr;
|
||
|
}
|
||
|
|
||
|
/***************************************************************************\
|
||
|
* RejectCheck
|
||
|
*
|
||
|
\***************************************************************************/
|
||
|
|
||
|
DWORD RejectCheck(PPP_CONFIG* pRecvBuf, PPP_CONFIG* pSendBuf, BOOL *pfRej)
|
||
|
{
|
||
|
PPP_OPTION *pROption = (PPP_OPTION*)pRecvBuf->Data;
|
||
|
PPP_OPTION *pSOption = (PPP_OPTION*)pSendBuf->Data;
|
||
|
WORD cbPacket = WireToHostFormat16(pRecvBuf->Length);
|
||
|
WORD cbLeft = cbPacket - PPP_CONFIG_HDR_LEN;
|
||
|
|
||
|
*pfRej = FALSE;
|
||
|
|
||
|
while (cbLeft > 0) {
|
||
|
|
||
|
if (cbLeft < pROption->Length) {
|
||
|
return ERROR_PPP_INVALID_PACKET;
|
||
|
}
|
||
|
|
||
|
if (pROption->Type == IPCP_IpCompression) {
|
||
|
|
||
|
*pfRej = TRUE;
|
||
|
CopyMemory((VOID*)pSOption, (VOID*)pROption, pROption->Length);
|
||
|
pSOption = (PPP_OPTION*)((BYTE*)pSOption + pROption->Length);
|
||
|
|
||
|
} else {
|
||
|
|
||
|
IPADDR ipaddr;
|
||
|
|
||
|
BOOL fBad = (pROption->Type != IPCP_IpAddress ||
|
||
|
pROption->Length != IPADDRESSOPTIONLEN);
|
||
|
|
||
|
if (!fBad) {
|
||
|
CopyMemory(&ipaddr, pROption->Data, sizeof(IPADDR));
|
||
|
}
|
||
|
|
||
|
if (fBad || ipaddr == 0) {
|
||
|
|
||
|
*pfRej = TRUE;
|
||
|
|
||
|
CopyMemory((VOID*)pSOption, (VOID*)pROption, pROption->Length);
|
||
|
pSOption = (PPP_OPTION*)((BYTE*)pSOption + pROption->Length);
|
||
|
|
||
|
} else {
|
||
|
gIp.IpAddrRemote = ipaddr;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
if (pROption->Length && pROption->Length < cbLeft) {
|
||
|
cbLeft -= pROption->Length;
|
||
|
} else {
|
||
|
cbLeft = 0;
|
||
|
}
|
||
|
|
||
|
pROption = (PPP_OPTION*)((BYTE*)pROption + pROption->Length);
|
||
|
}
|
||
|
|
||
|
if (*pfRej) {
|
||
|
pSendBuf->Code = CONFIG_REJ;
|
||
|
HostToWireFormat16((WORD)((BYTE*)pSOption - (BYTE*)pSendBuf), pSendBuf->Length);
|
||
|
}
|
||
|
|
||
|
return NO_ERROR;
|
||
|
}
|
||
|
|
||
|
/***************************************************************************\
|
||
|
* IpcpMakeConfigRequest
|
||
|
*
|
||
|
\***************************************************************************/
|
||
|
|
||
|
DWORD IpcpMakeConfigRequest(PPP_CONFIG *pSendConfig, DWORD cbSendConfig)
|
||
|
{
|
||
|
BYTE *pb = pSendConfig->Data;
|
||
|
WORD cbPacket = PPP_CONFIG_HDR_LEN;
|
||
|
|
||
|
AddIpAddressOption(pb, IPCP_IpAddress, gIp.IpAddrLocal);
|
||
|
cbPacket += IPADDRESSOPTIONLEN;
|
||
|
pb += IPADDRESSOPTIONLEN;
|
||
|
|
||
|
AddIpAddressOption(pb, IPCP_DnsIpAddress, gIp.IpAddrDns);
|
||
|
cbPacket += IPADDRESSOPTIONLEN;
|
||
|
pb += IPADDRESSOPTIONLEN;
|
||
|
|
||
|
HostToWireFormat16(cbPacket, pSendConfig->Length);
|
||
|
|
||
|
return NO_ERROR;
|
||
|
}
|
||
|
|
||
|
/***************************************************************************\
|
||
|
* IpcpMakeConfigResult
|
||
|
*
|
||
|
\***************************************************************************/
|
||
|
|
||
|
DWORD IpcpMakeConfigResult(PPP_CONFIG *pRecvBuf, PPP_CONFIG *pSendBuf,
|
||
|
DWORD cbSendBuf, BOOL fRejectNaks)
|
||
|
{
|
||
|
DWORD dwErr;
|
||
|
BOOL fRej;
|
||
|
WORD cbPacket;
|
||
|
|
||
|
dwErr = RejectCheck(pRecvBuf, pSendBuf, &fRej);
|
||
|
if (dwErr != 0) {
|
||
|
return dwErr;
|
||
|
}
|
||
|
|
||
|
if (fRej) {
|
||
|
return NO_ERROR;
|
||
|
}
|
||
|
|
||
|
cbPacket = WireToHostFormat16(pRecvBuf->Length);
|
||
|
CopyMemory(pSendBuf, pRecvBuf, cbPacket);
|
||
|
pSendBuf->Code = CONFIG_ACK;
|
||
|
|
||
|
return 0;
|
||
|
}
|
||
|
|
||
|
/***************************************************************************\
|
||
|
* IpcpConfigAckReceived
|
||
|
*
|
||
|
\***************************************************************************/
|
||
|
|
||
|
DWORD IpcpConfigAckReceived(PPP_CONFIG *pRecvBuf)
|
||
|
{
|
||
|
return NO_ERROR;
|
||
|
}
|
||
|
|
||
|
/***************************************************************************\
|
||
|
* IpcpConfigRejReceived
|
||
|
*
|
||
|
\***************************************************************************/
|
||
|
|
||
|
DWORD IpcpConfigRejReceived(PPP_CONFIG *pRecvBuf)
|
||
|
{
|
||
|
return NO_ERROR;
|
||
|
}
|
||
|
|
||
|
/***************************************************************************\
|
||
|
* IpcpConfigNakReceived
|
||
|
*
|
||
|
\***************************************************************************/
|
||
|
|
||
|
DWORD IpcpConfigNakReceived(PPP_CONFIG* pRecvBuf)
|
||
|
{
|
||
|
PPP_OPTION *pROption = (PPP_OPTION*)pRecvBuf->Data;
|
||
|
WORD cbPacket = WireToHostFormat16(pRecvBuf->Length);
|
||
|
WORD cbLeft = cbPacket - PPP_CONFIG_HDR_LEN;
|
||
|
IPADDR ipaddr;
|
||
|
|
||
|
while (cbLeft > 0) {
|
||
|
|
||
|
if (cbLeft < pROption->Length) {
|
||
|
return ERROR_PPP_INVALID_PACKET;
|
||
|
}
|
||
|
|
||
|
switch (pROption->Type) {
|
||
|
case IPCP_IpAddress:
|
||
|
if (pROption->Length != IPADDRESSOPTIONLEN) {
|
||
|
return ERROR_PPP_INVALID_PACKET;
|
||
|
}
|
||
|
|
||
|
CopyMemory(&ipaddr, pROption->Data, sizeof(IPADDR));
|
||
|
|
||
|
if (ipaddr == 0) {
|
||
|
return ERROR_PPP_INVALID_PACKET;
|
||
|
}
|
||
|
|
||
|
gIp.IpAddrLocal = ipaddr;
|
||
|
break;
|
||
|
|
||
|
case IPCP_DnsIpAddress:
|
||
|
if (pROption->Length != IPADDRESSOPTIONLEN) {
|
||
|
return ERROR_PPP_INVALID_PACKET;
|
||
|
}
|
||
|
|
||
|
CopyMemory(&gIp.IpAddrDns, pROption->Data, sizeof(IPADDR));
|
||
|
break;
|
||
|
}
|
||
|
|
||
|
if (pROption->Length && pROption->Length < cbLeft) {
|
||
|
cbLeft -= pROption->Length;
|
||
|
} else {
|
||
|
cbLeft = 0;
|
||
|
}
|
||
|
|
||
|
pROption = (PPP_OPTION*)((BYTE*)pROption + pROption->Length);
|
||
|
}
|
||
|
|
||
|
return NO_ERROR;
|
||
|
}
|
||
|
|
||
|
/***************************************************************************\
|
||
|
* IpcpBegin
|
||
|
*
|
||
|
\***************************************************************************/
|
||
|
|
||
|
DWORD IpcpBegin(VOID)
|
||
|
{
|
||
|
return NO_ERROR;
|
||
|
}
|
||
|
|
||
|
/***************************************************************************\
|
||
|
* IpcpEnd
|
||
|
*
|
||
|
\***************************************************************************/
|
||
|
|
||
|
DWORD IpcpEnd(VOID)
|
||
|
{
|
||
|
return NO_ERROR;
|
||
|
}
|
||
|
|
||
|
/***************************************************************************\
|
||
|
* GetIpcpInfo
|
||
|
*
|
||
|
\***************************************************************************/
|
||
|
|
||
|
VOID GetIpcpInfo(PPP_CP_INFO *pInfo)
|
||
|
{
|
||
|
ZeroMemory(pInfo, sizeof(PPP_CP_INFO));
|
||
|
pInfo->Protocol = PPP_IPCP_PROTOCOL;
|
||
|
pInfo->Recognize = MAX_IPCP_CODE;
|
||
|
pInfo->CP_Begin = IpcpBegin;
|
||
|
pInfo->CP_End = IpcpEnd;
|
||
|
pInfo->CP_MakeConfigRequest = IpcpMakeConfigRequest;
|
||
|
pInfo->CP_MakeConfigResult = IpcpMakeConfigResult;
|
||
|
pInfo->CP_ConfigAckReceived = IpcpConfigAckReceived;
|
||
|
pInfo->CP_ConfigRejReceived = IpcpConfigRejReceived;
|
||
|
pInfo->CP_ConfigNakReceived = IpcpConfigNakReceived;
|
||
|
}
|
||
|
|