You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
303 lines
7.6 KiB
303 lines
7.6 KiB
/********************************************************************/
|
|
/** Copyright(c) 1989 Microsoft Corporation. **/
|
|
/********************************************************************/
|
|
|
|
//***
|
|
//
|
|
// Filename: callback.c
|
|
//
|
|
// Description: Contains FSM code to handle and callback control protocol
|
|
//
|
|
// History:
|
|
// April 11,1993. NarenG Created original version.
|
|
//
|
|
|
|
#include <nt.h>
|
|
#include <ntrtl.h>
|
|
#include <nturtl.h> // needed for winbase.h
|
|
|
|
#include <windows.h> // Win32 base API's
|
|
#include <stdlib.h>
|
|
#include <string.h>
|
|
#include <wchar.h>
|
|
|
|
#include <lmcons.h>
|
|
#include <raserror.h>
|
|
#include <rasman.h>
|
|
#include <rasppp.h>
|
|
#include <pppcp.h>
|
|
#include <ppp.h>
|
|
#include <auth.h>
|
|
#include <callback.h>
|
|
#include <smevents.h>
|
|
#include <smaction.h>
|
|
#include <lcp.h>
|
|
#include <timer.h>
|
|
#include <rtutils.h>
|
|
#include <util.h>
|
|
#include <worker.h>
|
|
|
|
//**
|
|
//
|
|
// Call: CbStart
|
|
//
|
|
// Returns: none
|
|
//
|
|
// Description: Called to initiatialze the callback control protocol and to
|
|
// initiate to callback negotiation.
|
|
//
|
|
VOID
|
|
CbStart(
|
|
IN PCB * pPcb,
|
|
IN DWORD CpIndex
|
|
)
|
|
{
|
|
DWORD dwRetCode;
|
|
PPPCB_INPUT PppCbInput;
|
|
CPCB * pCpCb = GetPointerToCPCB( pPcb, CpIndex );
|
|
|
|
if ( NULL == pCpCb )
|
|
{
|
|
return;
|
|
}
|
|
|
|
PppCbInput.fServer = pPcb->fFlags & PCBFLAG_IS_SERVER;
|
|
PppCbInput.bfCallbackPrivilege = (BYTE)(pPcb->fCallbackPrivilege);
|
|
PppCbInput.CallbackDelay = ( pPcb->ConfigInfo.dwConfigMask &
|
|
PPPCFG_UseCallbackDelay )
|
|
? pPcb->ConfigInfo.dwCallbackDelay
|
|
: PppConfigInfo.dwCallbackDelay;
|
|
|
|
PppCbInput.pszCallbackNumber = pPcb->szCallbackNumber;
|
|
|
|
PppLog( 2, "CallbackPriv in CB = %x", PppCbInput.bfCallbackPrivilege );
|
|
|
|
dwRetCode = (CpTable[CpIndex].CpInfo.RasCpBegin)(&(pCpCb->pWorkBuf),
|
|
&PppCbInput);
|
|
|
|
if ( dwRetCode != NO_ERROR )
|
|
{
|
|
pPcb->LcpCb.dwError = dwRetCode;
|
|
|
|
NotifyCallerOfFailure( pPcb, dwRetCode );
|
|
|
|
return;
|
|
}
|
|
|
|
pCpCb->LastId = (DWORD)-1;
|
|
InitRestartCounters( pPcb, pCpCb );
|
|
|
|
CbWork( pPcb, CpIndex, NULL, NULL );
|
|
}
|
|
|
|
//**
|
|
//
|
|
// Call: CbStop
|
|
//
|
|
// Returns: none
|
|
//
|
|
// Description: Called to stop the callback control protocol machine.
|
|
//
|
|
VOID
|
|
CbStop(
|
|
IN PCB * pPcb,
|
|
IN DWORD CpIndex
|
|
)
|
|
{
|
|
CPCB * pCpCb = GetPointerToCPCB( pPcb, CpIndex );
|
|
|
|
if ( NULL == pCpCb )
|
|
{
|
|
return;
|
|
}
|
|
|
|
if ( pCpCb->LastId != (DWORD)-1 )
|
|
{
|
|
RemoveFromTimerQ(
|
|
pPcb->dwPortId,
|
|
pCpCb->LastId,
|
|
CpTable[CpIndex].CpInfo.Protocol,
|
|
FALSE,
|
|
TIMER_EVENT_TIMEOUT );
|
|
}
|
|
|
|
if ( pCpCb->pWorkBuf != NULL )
|
|
{
|
|
(CpTable[CpIndex].CpInfo.RasCpEnd)( pCpCb->pWorkBuf );
|
|
|
|
pCpCb->pWorkBuf = NULL;
|
|
}
|
|
}
|
|
|
|
//**
|
|
//
|
|
// Call: CbWork
|
|
//
|
|
// Returns: none
|
|
//
|
|
// Description: Called when and callback control protocol packet was received or
|
|
// a timeout ocurred or to initiate callback negotiation.
|
|
//
|
|
VOID
|
|
CbWork(
|
|
IN PCB * pPcb,
|
|
IN DWORD CpIndex,
|
|
IN PPP_CONFIG * pRecvConfig,
|
|
IN PPPCB_INPUT * pCbInput
|
|
)
|
|
{
|
|
DWORD dwRetCode;
|
|
CPCB * pCpCb = GetPointerToCPCB( pPcb, CpIndex );
|
|
PPP_CONFIG * pSendConfig = (PPP_CONFIG*)(pPcb->pSendBuf->Information);
|
|
PPPCB_RESULT CbResult;
|
|
DWORD dwLength;
|
|
|
|
if ( NULL == pCpCb )
|
|
{
|
|
return;
|
|
}
|
|
|
|
PPP_ASSERT( NULL != pCpCb->pWorkBuf );
|
|
|
|
dwRetCode = (CpTable[CpIndex].CpInfo.RasApMakeMessage)(
|
|
pCpCb->pWorkBuf,
|
|
pRecvConfig,
|
|
pSendConfig,
|
|
LCP_DEFAULT_MRU
|
|
- PPP_PACKET_HDR_LEN,
|
|
(PPPAP_RESULT*)&CbResult,
|
|
(PPPAP_INPUT*)pCbInput );
|
|
|
|
if ( dwRetCode != NO_ERROR )
|
|
{
|
|
if ( dwRetCode == ERROR_PPP_INVALID_PACKET )
|
|
{
|
|
PppLog(1,
|
|
"Silently discarding invalid callback packet on port %d",
|
|
pPcb->hPort );
|
|
|
|
return;
|
|
}
|
|
else
|
|
{
|
|
pPcb->LcpCb.dwError = dwRetCode;
|
|
|
|
NotifyCallerOfFailure( pPcb, dwRetCode );
|
|
|
|
return;
|
|
}
|
|
}
|
|
|
|
switch( CbResult.Action )
|
|
{
|
|
|
|
case APA_Send:
|
|
case APA_SendWithTimeout:
|
|
case APA_SendWithTimeout2:
|
|
case APA_SendAndDone:
|
|
|
|
HostToWireFormat16( (WORD)CpTable[CpIndex].CpInfo.Protocol,
|
|
(PBYTE)(pPcb->pSendBuf->Protocol) );
|
|
|
|
dwLength = WireToHostFormat16( pSendConfig->Length );
|
|
|
|
LogPPPPacket(FALSE,pPcb,pPcb->pSendBuf,dwLength+PPP_PACKET_HDR_LEN);
|
|
|
|
if ( ( dwRetCode = PortSendOrDisconnect( pPcb,
|
|
(dwLength + PPP_PACKET_HDR_LEN)))
|
|
!= NO_ERROR )
|
|
{
|
|
return;
|
|
}
|
|
|
|
pCpCb->LastId = (DWORD)-1;
|
|
|
|
if ( ( CbResult.Action == APA_SendWithTimeout ) ||
|
|
( CbResult.Action == APA_SendWithTimeout2 ) )
|
|
{
|
|
pCpCb->LastId = CbResult.bIdExpected;
|
|
|
|
InsertInTimerQ( pPcb->dwPortId,
|
|
pPcb->hPort,
|
|
pCpCb->LastId,
|
|
CpTable[CpIndex].CpInfo.Protocol,
|
|
FALSE,
|
|
TIMER_EVENT_TIMEOUT,
|
|
pPcb->RestartTimer );
|
|
|
|
//
|
|
// For SendWithTimeout2 we increment the ConfigRetryCount. This
|
|
// means send with infinite retry count
|
|
//
|
|
|
|
if ( CbResult.Action == APA_SendWithTimeout2 )
|
|
{
|
|
(pCpCb->ConfigRetryCount)++;
|
|
}
|
|
}
|
|
|
|
if ( CbResult.Action != APA_SendAndDone )
|
|
break;
|
|
|
|
case APA_Done:
|
|
|
|
if ( CbResult.bfCallbackPrivilege == RASPRIV_NoCallback )
|
|
{
|
|
//
|
|
// If no callback was negotiated we continue on to the next
|
|
// phase.
|
|
//
|
|
|
|
FsmThisLayerUp( pPcb, CpIndex );
|
|
}
|
|
else
|
|
{
|
|
if ( pPcb->fFlags & PCBFLAG_IS_SERVER )
|
|
{
|
|
//
|
|
// If we are the server side we save the callback info
|
|
//
|
|
|
|
strcpy( pPcb->szCallbackNumber, CbResult.szCallbackNumber );
|
|
|
|
pPcb->ConfigInfo.dwCallbackDelay = CbResult.CallbackDelay;
|
|
|
|
}
|
|
else
|
|
{
|
|
//
|
|
// We are the client side so, we tell the server that we
|
|
// bringing the link down and we tell the client to
|
|
// prepare for callback
|
|
//
|
|
|
|
FsmClose( pPcb, LCP_INDEX );
|
|
}
|
|
|
|
pPcb->fFlags |= PCBFLAG_DOING_CALLBACK;
|
|
}
|
|
|
|
break;
|
|
|
|
case APA_NoAction:
|
|
|
|
//
|
|
// If we are on the client then we need to get the callback number
|
|
// from the user.
|
|
//
|
|
|
|
|
|
if ( ( !(pPcb->fFlags & PCBFLAG_IS_SERVER) &&
|
|
( CbResult.fGetCallbackNumberFromUser ) ) )
|
|
{
|
|
NotifyCaller( pPcb, PPPMSG_CallbackRequest, NULL );
|
|
}
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
break;
|
|
}
|
|
|
|
}
|