304 lines
7.3 KiB
C
304 lines
7.3 KiB
C
/********************************************************************/
|
||
/** 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;
|
||
}
|
||
|
||
}
|