Source code of Windows XP (NT5)
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.3 KiB

  1. /********************************************************************/
  2. /** Copyright(c) 1989 Microsoft Corporation. **/
  3. /********************************************************************/
  4. //***
  5. //
  6. // Filename: callback.c
  7. //
  8. // Description: Contains FSM code to handle and callback control protocol
  9. //
  10. // History:
  11. // April 11,1993. NarenG Created original version.
  12. //
  13. #include <nt.h>
  14. #include <ntrtl.h>
  15. #include <nturtl.h> // needed for winbase.h
  16. #include <windows.h> // Win32 base API's
  17. #include <stdlib.h>
  18. #include <string.h>
  19. #include <wchar.h>
  20. #include <lmcons.h>
  21. #include <raserror.h>
  22. #include <rasman.h>
  23. #include <rasppp.h>
  24. #include <pppcp.h>
  25. #include <ppp.h>
  26. #include <auth.h>
  27. #include <callback.h>
  28. #include <smevents.h>
  29. #include <smaction.h>
  30. #include <lcp.h>
  31. #include <timer.h>
  32. #include <rtutils.h>
  33. #include <util.h>
  34. #include <worker.h>
  35. //**
  36. //
  37. // Call: CbStart
  38. //
  39. // Returns: none
  40. //
  41. // Description: Called to initiatialze the callback control protocol and to
  42. // initiate to callback negotiation.
  43. //
  44. VOID
  45. CbStart(
  46. IN PCB * pPcb,
  47. IN DWORD CpIndex
  48. )
  49. {
  50. DWORD dwRetCode;
  51. PPPCB_INPUT PppCbInput;
  52. CPCB * pCpCb = GetPointerToCPCB( pPcb, CpIndex );
  53. if ( NULL == pCpCb )
  54. {
  55. return;
  56. }
  57. PppCbInput.fServer = pPcb->fFlags & PCBFLAG_IS_SERVER;
  58. PppCbInput.bfCallbackPrivilege = (BYTE)(pPcb->fCallbackPrivilege);
  59. PppCbInput.CallbackDelay = ( pPcb->ConfigInfo.dwConfigMask &
  60. PPPCFG_UseCallbackDelay )
  61. ? pPcb->ConfigInfo.dwCallbackDelay
  62. : PppConfigInfo.dwCallbackDelay;
  63. PppCbInput.pszCallbackNumber = pPcb->szCallbackNumber;
  64. PppLog( 2, "CallbackPriv in CB = %x", PppCbInput.bfCallbackPrivilege );
  65. dwRetCode = (CpTable[CpIndex].CpInfo.RasCpBegin)(&(pCpCb->pWorkBuf),
  66. &PppCbInput);
  67. if ( dwRetCode != NO_ERROR )
  68. {
  69. pPcb->LcpCb.dwError = dwRetCode;
  70. NotifyCallerOfFailure( pPcb, dwRetCode );
  71. return;
  72. }
  73. pCpCb->LastId = (DWORD)-1;
  74. InitRestartCounters( pPcb, pCpCb );
  75. CbWork( pPcb, CpIndex, NULL, NULL );
  76. }
  77. //**
  78. //
  79. // Call: CbStop
  80. //
  81. // Returns: none
  82. //
  83. // Description: Called to stop the callback control protocol machine.
  84. //
  85. VOID
  86. CbStop(
  87. IN PCB * pPcb,
  88. IN DWORD CpIndex
  89. )
  90. {
  91. CPCB * pCpCb = GetPointerToCPCB( pPcb, CpIndex );
  92. if ( NULL == pCpCb )
  93. {
  94. return;
  95. }
  96. if ( pCpCb->LastId != (DWORD)-1 )
  97. {
  98. RemoveFromTimerQ(
  99. pPcb->dwPortId,
  100. pCpCb->LastId,
  101. CpTable[CpIndex].CpInfo.Protocol,
  102. FALSE,
  103. TIMER_EVENT_TIMEOUT );
  104. }
  105. if ( pCpCb->pWorkBuf != NULL )
  106. {
  107. (CpTable[CpIndex].CpInfo.RasCpEnd)( pCpCb->pWorkBuf );
  108. pCpCb->pWorkBuf = NULL;
  109. }
  110. }
  111. //**
  112. //
  113. // Call: CbWork
  114. //
  115. // Returns: none
  116. //
  117. // Description: Called when and callback control protocol packet was received or
  118. // a timeout ocurred or to initiate callback negotiation.
  119. //
  120. VOID
  121. CbWork(
  122. IN PCB * pPcb,
  123. IN DWORD CpIndex,
  124. IN PPP_CONFIG * pRecvConfig,
  125. IN PPPCB_INPUT * pCbInput
  126. )
  127. {
  128. DWORD dwRetCode;
  129. CPCB * pCpCb = GetPointerToCPCB( pPcb, CpIndex );
  130. PPP_CONFIG * pSendConfig = (PPP_CONFIG*)(pPcb->pSendBuf->Information);
  131. PPPCB_RESULT CbResult;
  132. DWORD dwLength;
  133. if ( NULL == pCpCb )
  134. {
  135. return;
  136. }
  137. PPP_ASSERT( NULL != pCpCb->pWorkBuf );
  138. dwRetCode = (CpTable[CpIndex].CpInfo.RasApMakeMessage)(
  139. pCpCb->pWorkBuf,
  140. pRecvConfig,
  141. pSendConfig,
  142. LCP_DEFAULT_MRU
  143. - PPP_PACKET_HDR_LEN,
  144. (PPPAP_RESULT*)&CbResult,
  145. (PPPAP_INPUT*)pCbInput );
  146. if ( dwRetCode != NO_ERROR )
  147. {
  148. if ( dwRetCode == ERROR_PPP_INVALID_PACKET )
  149. {
  150. PppLog(1,
  151. "Silently discarding invalid callback packet on port %d",
  152. pPcb->hPort );
  153. return;
  154. }
  155. else
  156. {
  157. pPcb->LcpCb.dwError = dwRetCode;
  158. NotifyCallerOfFailure( pPcb, dwRetCode );
  159. return;
  160. }
  161. }
  162. switch( CbResult.Action )
  163. {
  164. case APA_Send:
  165. case APA_SendWithTimeout:
  166. case APA_SendWithTimeout2:
  167. case APA_SendAndDone:
  168. HostToWireFormat16( (WORD)CpTable[CpIndex].CpInfo.Protocol,
  169. (PBYTE)(pPcb->pSendBuf->Protocol) );
  170. dwLength = WireToHostFormat16( pSendConfig->Length );
  171. LogPPPPacket(FALSE,pPcb,pPcb->pSendBuf,dwLength+PPP_PACKET_HDR_LEN);
  172. if ( ( dwRetCode = PortSendOrDisconnect( pPcb,
  173. (dwLength + PPP_PACKET_HDR_LEN)))
  174. != NO_ERROR )
  175. {
  176. return;
  177. }
  178. pCpCb->LastId = (DWORD)-1;
  179. if ( ( CbResult.Action == APA_SendWithTimeout ) ||
  180. ( CbResult.Action == APA_SendWithTimeout2 ) )
  181. {
  182. pCpCb->LastId = CbResult.bIdExpected;
  183. InsertInTimerQ( pPcb->dwPortId,
  184. pPcb->hPort,
  185. pCpCb->LastId,
  186. CpTable[CpIndex].CpInfo.Protocol,
  187. FALSE,
  188. TIMER_EVENT_TIMEOUT,
  189. pPcb->RestartTimer );
  190. //
  191. // For SendWithTimeout2 we increment the ConfigRetryCount. This
  192. // means send with infinite retry count
  193. //
  194. if ( CbResult.Action == APA_SendWithTimeout2 )
  195. {
  196. (pCpCb->ConfigRetryCount)++;
  197. }
  198. }
  199. if ( CbResult.Action != APA_SendAndDone )
  200. break;
  201. case APA_Done:
  202. if ( CbResult.bfCallbackPrivilege == RASPRIV_NoCallback )
  203. {
  204. //
  205. // If no callback was negotiated we continue on to the next
  206. // phase.
  207. //
  208. FsmThisLayerUp( pPcb, CpIndex );
  209. }
  210. else
  211. {
  212. if ( pPcb->fFlags & PCBFLAG_IS_SERVER )
  213. {
  214. //
  215. // If we are the server side we save the callback info
  216. //
  217. strcpy( pPcb->szCallbackNumber, CbResult.szCallbackNumber );
  218. pPcb->ConfigInfo.dwCallbackDelay = CbResult.CallbackDelay;
  219. }
  220. else
  221. {
  222. //
  223. // We are the client side so, we tell the server that we
  224. // bringing the link down and we tell the client to
  225. // prepare for callback
  226. //
  227. FsmClose( pPcb, LCP_INDEX );
  228. }
  229. pPcb->fFlags |= PCBFLAG_DOING_CALLBACK;
  230. }
  231. break;
  232. case APA_NoAction:
  233. //
  234. // If we are on the client then we need to get the callback number
  235. // from the user.
  236. //
  237. if ( ( !(pPcb->fFlags & PCBFLAG_IS_SERVER) &&
  238. ( CbResult.fGetCallbackNumberFromUser ) ) )
  239. {
  240. NotifyCaller( pPcb, PPPMSG_CallbackRequest, NULL );
  241. }
  242. break;
  243. default:
  244. break;
  245. }
  246. }