Leaked source code of windows server 2003
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.

2152 lines
65 KiB

  1. /********************************************************************/
  2. /** Copyright(c) 1989 Microsoft Corporation. **/
  3. /********************************************************************/
  4. //***
  5. //
  6. // Filename: rasccp.c
  7. //
  8. // Description: Contains entry points to configure CCP.
  9. //
  10. // History: April 11,1994. NarenG Created original version.
  11. //
  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 <rtutils.h>
  23. #include <rasman.h>
  24. #include <pppcp.h>
  25. #define INCL_HOSTWIRE
  26. #define INCL_ENCRYPT
  27. #define INCL_RASAUTHATTRIBUTES
  28. #include <ppputil.h>
  29. #define CCPGLOBALS
  30. #include <rasccp.h>
  31. //**
  32. //
  33. // Call: TraceCcp
  34. //
  35. // Description:
  36. //
  37. VOID
  38. TraceCcp(
  39. CHAR * Format,
  40. ...
  41. )
  42. {
  43. va_list arglist;
  44. va_start(arglist, Format);
  45. TraceVprintfEx( DwCcpTraceId, TRACE_RASCCP, Format, arglist);
  46. va_end(arglist);
  47. }
  48. //**
  49. //
  50. // Call: CcpInit
  51. //
  52. // Returns: NO_ERROR - Success
  53. // Non-zero returns - Failure
  54. //
  55. // Description:
  56. //
  57. DWORD
  58. CcpInit(
  59. IN BOOL fInitialize
  60. )
  61. {
  62. if ( fInitialize )
  63. {
  64. DwCcpTraceId = TraceRegister("RASCCP");
  65. }
  66. else
  67. {
  68. TraceDeregister( DwCcpTraceId );
  69. }
  70. return( NO_ERROR );
  71. }
  72. //**
  73. //
  74. // Call: CcpBegin
  75. //
  76. // Returns: NO_ERROR - Success
  77. // non-zero error - Failure
  78. //
  79. //
  80. // Description: Called once before any other call to CCP is made. Allocate
  81. // a work buffer and initialize it.
  82. //
  83. DWORD
  84. CcpBegin(
  85. IN OUT VOID** ppWorkBuf,
  86. IN VOID* pInfo
  87. )
  88. {
  89. CCPCB * pCcpCb;
  90. DWORD dwRetCode;
  91. RAS_AUTH_ATTRIBUTE * pAttribute;
  92. RAS_AUTH_ATTRIBUTE * pAttributeSend;
  93. RAS_AUTH_ATTRIBUTE * pAttributeRecv;
  94. DWORD fEncryptionTypes = 0;
  95. BOOL fDisableEncryption = FALSE;
  96. DWORD dwConfigMask =
  97. ((PPPCP_INIT*)pInfo)->PppConfigInfo.dwConfigMask;
  98. *ppWorkBuf = LocalAlloc( LPTR, sizeof( CCPCB ) );
  99. if ( *ppWorkBuf == NULL )
  100. {
  101. return( GetLastError() );
  102. }
  103. pCcpCb = (CCPCB *)*ppWorkBuf;
  104. pCcpCb->fServer = ((PPPCP_INIT*)pInfo)->fServer;
  105. pCcpCb->hPort = ((PPPCP_INIT*)pInfo)->hPort;
  106. pCcpCb->dwDeviceType = ((PPPCP_INIT*)pInfo)->dwDeviceType;
  107. pCcpCb->fForceEncryption = FALSE;
  108. pCcpCb->fDisableCompression = !( dwConfigMask & PPPCFG_UseSwCompression );
  109. fDisableEncryption = dwConfigMask & PPPCFG_DisableEncryption;
  110. if ( pCcpCb->fServer )
  111. {
  112. if ( RAS_DEVICE_TYPE( pCcpCb->dwDeviceType ) == RDT_Tunnel_L2tp )
  113. {
  114. //
  115. // Allow all types of MPPE, including No Encryption
  116. //
  117. fEncryptionTypes = ( MSTYPE_ENCRYPTION_40 |
  118. MSTYPE_ENCRYPTION_40F |
  119. MSTYPE_ENCRYPTION_56 |
  120. MSTYPE_ENCRYPTION_128 );
  121. }
  122. else
  123. {
  124. //
  125. // Is there an encryption policy attribute
  126. //
  127. pAttribute = RasAuthAttributeGetVendorSpecific(
  128. 311,
  129. 7,
  130. ((PPPCP_INIT *)pInfo)->pAttributes );
  131. if ( pAttribute != NULL )
  132. {
  133. //
  134. // See if we have to force encryption
  135. //
  136. if ( WireToHostFormat32( ((PBYTE)(pAttribute->Value))+6 ) == 2 )
  137. {
  138. fDisableEncryption = FALSE;
  139. pCcpCb->fForceEncryption = TRUE;
  140. TraceCcp("Will force encryption");
  141. }
  142. }
  143. //
  144. // Now find out what type of encryption is
  145. // permitted/disallowed/required
  146. //
  147. pAttribute = RasAuthAttributeGetVendorSpecific(
  148. 311,
  149. 8,
  150. ((PPPCP_INIT *)pInfo)->pAttributes );
  151. if ( pAttribute != NULL )
  152. {
  153. DWORD dwEncryptionTypes =
  154. WireToHostFormat32(((PBYTE)(pAttribute->Value))+6);
  155. if ( dwEncryptionTypes & 0x00000002 )
  156. {
  157. fEncryptionTypes = MSTYPE_ENCRYPTION_40 |
  158. MSTYPE_ENCRYPTION_40F;
  159. }
  160. if ( dwEncryptionTypes & 0x00000004 )
  161. {
  162. fEncryptionTypes |= MSTYPE_ENCRYPTION_128;
  163. }
  164. if ( dwEncryptionTypes & 0x00000008 )
  165. {
  166. fEncryptionTypes |= MSTYPE_ENCRYPTION_56;
  167. }
  168. if ( fEncryptionTypes == 0 )
  169. {
  170. fDisableEncryption = TRUE;
  171. pCcpCb->fForceEncryption = FALSE;
  172. TraceCcp("Will not force encryption: type not specified");
  173. }
  174. }
  175. else
  176. {
  177. fEncryptionTypes = ( MSTYPE_ENCRYPTION_40 |
  178. MSTYPE_ENCRYPTION_40F |
  179. MSTYPE_ENCRYPTION_56 |
  180. MSTYPE_ENCRYPTION_128 );
  181. }
  182. }
  183. TraceCcp("EncryptionTypes: 0x%x", fEncryptionTypes);
  184. }
  185. else
  186. {
  187. //
  188. // If client is forcing encryption
  189. //
  190. if ( dwConfigMask & PPPCFG_RequireEncryption )
  191. {
  192. fEncryptionTypes |= ( MSTYPE_ENCRYPTION_40 |
  193. MSTYPE_ENCRYPTION_40F |
  194. MSTYPE_ENCRYPTION_56 );
  195. fDisableEncryption = FALSE;
  196. pCcpCb->fForceEncryption = TRUE;
  197. TraceCcp("Encryption");
  198. }
  199. if ( dwConfigMask & PPPCFG_RequireStrongEncryption )
  200. {
  201. //
  202. // If client is forcing strong encryption
  203. //
  204. fEncryptionTypes |= MSTYPE_ENCRYPTION_128;
  205. fDisableEncryption = FALSE;
  206. pCcpCb->fForceEncryption = TRUE;
  207. TraceCcp("Strong encryption");
  208. }
  209. //
  210. // If we are not disabling encryption and we are not forcing encryption
  211. // either.
  212. //
  213. if ( ( !fDisableEncryption ) && ( fEncryptionTypes == 0 ) )
  214. {
  215. //
  216. // Allow these types
  217. //
  218. fDisableEncryption = FALSE;
  219. pCcpCb->fForceEncryption = FALSE;
  220. fEncryptionTypes = ( MSTYPE_ENCRYPTION_40 |
  221. MSTYPE_ENCRYPTION_40F |
  222. MSTYPE_ENCRYPTION_56 |
  223. MSTYPE_ENCRYPTION_128 );
  224. TraceCcp("Not disabling encryption; Not forcing encryption");
  225. }
  226. }
  227. //
  228. // Now check if we got encryption keys, if not then we disable encryption
  229. //
  230. pAttribute = RasAuthAttributeGetVendorSpecific(
  231. 311,
  232. 12,
  233. ((PPPCP_INIT *)pInfo)->pAttributes );
  234. pAttributeSend = RasAuthAttributeGetVendorSpecific(
  235. 311,
  236. 16,
  237. ((PPPCP_INIT *)pInfo)->pAttributes );
  238. pAttributeRecv = RasAuthAttributeGetVendorSpecific(
  239. 311,
  240. 17,
  241. ((PPPCP_INIT *)pInfo)->pAttributes );
  242. if ( ( pAttribute == NULL )
  243. && ( ( pAttributeSend == NULL )
  244. || ( pAttributeRecv == NULL ) ) )
  245. {
  246. TraceCcp("No MPPE keys were obtained");
  247. if ( pCcpCb->fForceEncryption )
  248. {
  249. LocalFree( pCcpCb );
  250. return( ERROR_NO_LOCAL_ENCRYPTION );
  251. }
  252. fDisableEncryption = TRUE;
  253. pCcpCb->fForceEncryption = FALSE;
  254. fEncryptionTypes = ( MSTYPE_ENCRYPTION_40 |
  255. MSTYPE_ENCRYPTION_40F |
  256. MSTYPE_ENCRYPTION_56 |
  257. MSTYPE_ENCRYPTION_128 );
  258. }
  259. //
  260. // Get Send and Recv compression information
  261. //
  262. dwRetCode = RasCompressionGetInfo( pCcpCb->hPort,
  263. &(pCcpCb->Local.Want.CompInfo),
  264. &(pCcpCb->Remote.Want.CompInfo) );
  265. if ( dwRetCode != NO_ERROR )
  266. {
  267. LocalFree( pCcpCb );
  268. return( dwRetCode );
  269. }
  270. TraceCcp("Send capabilites from NDISWAN = 0x%x",
  271. pCcpCb->Local.Want.CompInfo.RCI_MSCompressionType );
  272. TraceCcp("Receive capabilites from NDISWAN = 0x%x",
  273. pCcpCb->Remote.Want.CompInfo.RCI_MSCompressionType );
  274. TraceCcp("Send RCI_MacCompressionType = 0x%x",
  275. pCcpCb->Local.Want.CompInfo.RCI_MacCompressionType );
  276. TraceCcp("Receive RCI_MacCompressionType = 0x%x",
  277. pCcpCb->Remote.Want.CompInfo.RCI_MacCompressionType );
  278. //
  279. // Ignore NT31RAS capability.
  280. //
  281. if ( pCcpCb->Local.Want.CompInfo.RCI_MacCompressionType
  282. == CCP_OPTION_MSNT31RAS )
  283. {
  284. pCcpCb->Local.Want.CompInfo.RCI_MacCompressionType = CCP_OPTION_MAX + 1;
  285. }
  286. if (pCcpCb->Remote.Want.CompInfo.RCI_MacCompressionType
  287. == CCP_OPTION_MSNT31RAS )
  288. {
  289. pCcpCb->Remote.Want.CompInfo.RCI_MacCompressionType = CCP_OPTION_MAX+1;
  290. }
  291. //
  292. // Set up local or send information.
  293. //
  294. pCcpCb->Local.Want.Negotiate = 0;
  295. if ( pCcpCb->Local.Want.CompInfo.RCI_MSCompressionType != 0 )
  296. {
  297. pCcpCb->Local.Want.Negotiate = CCP_N_MSPPC;
  298. }
  299. if ( pCcpCb->Local.Want.CompInfo.RCI_MacCompressionType <= CCP_OPTION_MAX )
  300. {
  301. if ( pCcpCb->Local.Want.CompInfo.RCI_MacCompressionType ==
  302. CCP_OPTION_OUI )
  303. {
  304. pCcpCb->Local.Want.Negotiate |= CCP_N_OUI;
  305. }
  306. else
  307. {
  308. pCcpCb->Local.Want.Negotiate |= CCP_N_PUBLIC;
  309. }
  310. }
  311. if ( pCcpCb->fForceEncryption )
  312. {
  313. //
  314. // Make sure NDISWAN supports the required encryption types
  315. //
  316. if ( !( pCcpCb->Local.Want.CompInfo.RCI_MSCompressionType &
  317. fEncryptionTypes ))
  318. {
  319. LocalFree( pCcpCb );
  320. TraceCcp("Encryption type(s) 0x%x not supported locally",
  321. fEncryptionTypes );
  322. return( ERROR_NO_LOCAL_ENCRYPTION );
  323. }
  324. //
  325. // Turn off everything else
  326. //
  327. pCcpCb->Local.Want.CompInfo.RCI_MSCompressionType &=
  328. ( fEncryptionTypes |
  329. MSTYPE_HISTORYLESS |
  330. MSTYPE_COMPRESSION );
  331. TraceCcp("Send Encryption is Forced 0x%x",
  332. pCcpCb->Local.Want.CompInfo.RCI_MSCompressionType );
  333. pCcpCb->Local.Want.Negotiate &= ~( CCP_N_PUBLIC | CCP_N_OUI );
  334. }
  335. if ( pCcpCb->fDisableCompression )
  336. {
  337. pCcpCb->Local.Want.Negotiate &= ( ~CCP_N_PUBLIC & ~CCP_N_OUI );
  338. pCcpCb->Local.Want.CompInfo.RCI_MSCompressionType&=~MSTYPE_COMPRESSION;
  339. TraceCcp("Send Compression is Disabled");
  340. }
  341. if ( fDisableEncryption )
  342. {
  343. pCcpCb->Local.Want.CompInfo.RCI_MSCompressionType &=
  344. ~( MSTYPE_ENCRYPTION_40 |
  345. MSTYPE_ENCRYPTION_40F |
  346. MSTYPE_ENCRYPTION_56 |
  347. MSTYPE_ENCRYPTION_128 );
  348. TraceCcp("Send Encryption is Disabled 0x%x", fEncryptionTypes );
  349. }
  350. //
  351. // If we neither force nor disable any encryption types, then we set the
  352. // types allowed
  353. //
  354. if ( (!fDisableEncryption) && (!pCcpCb->fForceEncryption) )
  355. {
  356. DWORD dwEncryptionTypesAllowed =
  357. pCcpCb->Local.Want.CompInfo.RCI_MSCompressionType & fEncryptionTypes;
  358. pCcpCb->Local.Want.CompInfo.RCI_MSCompressionType &=
  359. ~( MSTYPE_ENCRYPTION_40 |
  360. MSTYPE_ENCRYPTION_40F |
  361. MSTYPE_ENCRYPTION_56 |
  362. MSTYPE_ENCRYPTION_128 );
  363. pCcpCb->Local.Want.CompInfo.RCI_MSCompressionType |=
  364. dwEncryptionTypesAllowed;
  365. TraceCcp("Send Encryption is Allowed 0x%x", dwEncryptionTypesAllowed );
  366. }
  367. pCcpCb->Local.Work = pCcpCb->Local.Want;
  368. //
  369. // If we do not want any compression or encryption on the local side
  370. // we do not send, or accept NAKs to, negotiate the MSPPC option
  371. //
  372. if ( ( pCcpCb->Local.Want.CompInfo.RCI_MSCompressionType &
  373. ( MSTYPE_ENCRYPTION_40 |
  374. MSTYPE_ENCRYPTION_40F |
  375. MSTYPE_ENCRYPTION_56 |
  376. MSTYPE_ENCRYPTION_128 |
  377. MSTYPE_COMPRESSION ) )
  378. == 0 )
  379. {
  380. pCcpCb->Local.Want.Negotiate &= ~CCP_N_MSPPC;
  381. TraceCcp("We do not want any compression or encryption on the local "
  382. "side");
  383. }
  384. //
  385. // If we do not require encryption locally then do not request for it
  386. //
  387. if ( !( pCcpCb->fForceEncryption ) )
  388. {
  389. pCcpCb->Local.Work.CompInfo.RCI_MSCompressionType &=
  390. ~( MSTYPE_ENCRYPTION_40 |
  391. MSTYPE_ENCRYPTION_40F |
  392. MSTYPE_ENCRYPTION_56 |
  393. MSTYPE_ENCRYPTION_128 );
  394. TraceCcp("We do not require encryption locally; we won't request for "
  395. "it");
  396. }
  397. //
  398. // Set up remote or receive information
  399. //
  400. pCcpCb->Remote.Want.Negotiate = 0;
  401. if (pCcpCb->Remote.Want.CompInfo.RCI_MSCompressionType != 0 )
  402. {
  403. pCcpCb->Remote.Want.Negotiate = CCP_N_MSPPC;
  404. }
  405. if ( pCcpCb->Remote.Want.CompInfo.RCI_MacCompressionType <= CCP_OPTION_MAX )
  406. {
  407. if ( pCcpCb->Remote.Want.CompInfo.RCI_MacCompressionType ==
  408. CCP_OPTION_OUI )
  409. {
  410. pCcpCb->Remote.Want.Negotiate |= CCP_N_OUI;
  411. }
  412. else
  413. {
  414. pCcpCb->Remote.Want.Negotiate |= CCP_N_PUBLIC;
  415. }
  416. }
  417. if ( pCcpCb->fForceEncryption )
  418. {
  419. if ( !( pCcpCb->Remote.Want.CompInfo.RCI_MSCompressionType &
  420. fEncryptionTypes ) )
  421. {
  422. TraceCcp("Encryption type(s) 0x%x not supported locally",
  423. fEncryptionTypes );
  424. LocalFree( pCcpCb );
  425. return( ERROR_NO_LOCAL_ENCRYPTION );
  426. }
  427. pCcpCb->Remote.Want.CompInfo.RCI_MSCompressionType &=
  428. ( fEncryptionTypes |
  429. MSTYPE_HISTORYLESS |
  430. MSTYPE_COMPRESSION );
  431. TraceCcp("Receive Encryption is Forced 0x%x",
  432. pCcpCb->Remote.Want.CompInfo.RCI_MSCompressionType );
  433. pCcpCb->Remote.Want.Negotiate &= ~( CCP_N_PUBLIC | CCP_N_OUI );
  434. }
  435. if ( pCcpCb->fDisableCompression )
  436. {
  437. pCcpCb->Remote.Want.Negotiate &= ( ~CCP_N_PUBLIC & ~CCP_N_OUI );
  438. pCcpCb->Remote.Want.CompInfo.RCI_MSCompressionType&=~MSTYPE_COMPRESSION;
  439. TraceCcp("Receive Compression is disabled");
  440. }
  441. if ( fDisableEncryption )
  442. {
  443. pCcpCb->Remote.Want.CompInfo.RCI_MSCompressionType &=
  444. ~( MSTYPE_ENCRYPTION_40 |
  445. MSTYPE_ENCRYPTION_40F |
  446. MSTYPE_ENCRYPTION_56 |
  447. MSTYPE_ENCRYPTION_128 );
  448. TraceCcp("Receive Encryption is Disabled 0x%x", fEncryptionTypes );
  449. }
  450. //
  451. // If we neither force or disable any encryption types then we set the
  452. // types allowed
  453. //
  454. if ( (!fDisableEncryption) && (!pCcpCb->fForceEncryption) )
  455. {
  456. DWORD dwEncryptionTypesAllowed =
  457. pCcpCb->Remote.Want.CompInfo.RCI_MSCompressionType & fEncryptionTypes;
  458. pCcpCb->Remote.Want.CompInfo.RCI_MSCompressionType &=
  459. ~( MSTYPE_ENCRYPTION_40 |
  460. MSTYPE_ENCRYPTION_40F |
  461. MSTYPE_ENCRYPTION_56 |
  462. MSTYPE_ENCRYPTION_128 );
  463. pCcpCb->Remote.Want.CompInfo.RCI_MSCompressionType |=
  464. dwEncryptionTypesAllowed;
  465. TraceCcp("Receive Encryption is Allowed 0x%x", dwEncryptionTypesAllowed );
  466. }
  467. //
  468. // If we do not want to receive any compression or encryption from the
  469. // remote side, we do not ACK, or accept CONFIG-REQs to, negotiate the
  470. // MSPPC option
  471. //
  472. if ( ( pCcpCb->Remote.Want.CompInfo.RCI_MSCompressionType &
  473. ( MSTYPE_ENCRYPTION_40 |
  474. MSTYPE_ENCRYPTION_40F |
  475. MSTYPE_ENCRYPTION_56 |
  476. MSTYPE_ENCRYPTION_128 |
  477. MSTYPE_COMPRESSION ) )
  478. == 0 )
  479. {
  480. pCcpCb->Remote.Want.Negotiate &= ~CCP_N_MSPPC;
  481. TraceCcp("We do not want to receive any compression or encryption "
  482. "from the remote side");
  483. }
  484. if ( ( pCcpCb->Remote.Want.Negotiate == 0 ) &&
  485. ( pCcpCb->Local.Want.Negotiate == 0 ) )
  486. {
  487. TraceCcp("ERROR_PROTOCOL_NOT_CONFIGURED");
  488. LocalFree( pCcpCb );
  489. return( ERROR_PROTOCOL_NOT_CONFIGURED );
  490. }
  491. if ( pCcpCb->fForceEncryption )
  492. {
  493. TraceCcp("ForceEncryption");
  494. pCcpCb->Local.Want.CompInfo.RCI_Flags = CCP_PAUSE_DATA;
  495. pCcpCb->Remote.Want.CompInfo.RCI_Flags = CCP_PAUSE_DATA;
  496. dwRetCode = RasCompressionSetInfo( pCcpCb->hPort,
  497. &(pCcpCb->Local.Want.CompInfo),
  498. &(pCcpCb->Remote.Want.CompInfo) );
  499. if ( dwRetCode != NO_ERROR )
  500. {
  501. LocalFree( pCcpCb );
  502. return( dwRetCode );
  503. }
  504. }
  505. return( NO_ERROR );
  506. }
  507. //**
  508. //
  509. // Call: CcpEnd
  510. //
  511. // Returns: NO_ERROR - Success
  512. //
  513. // Description: Frees the CCP work buffer.
  514. //
  515. DWORD
  516. CcpEnd(
  517. IN VOID * pWorkBuf
  518. )
  519. {
  520. TraceCcp( "CcpEnd Called" );
  521. if ( pWorkBuf != NULL )
  522. {
  523. LocalFree( pWorkBuf );
  524. }
  525. return( NO_ERROR );
  526. }
  527. //**
  528. //
  529. // Call: CcpReset
  530. //
  531. // Returns: NO_ERROR - Success
  532. //
  533. // Description: Called to reset the state of CCP. Will re-initialize the work
  534. // buffer.
  535. //
  536. DWORD
  537. CcpReset(
  538. IN VOID * pWorkBuf
  539. )
  540. {
  541. return( NO_ERROR );
  542. }
  543. //**
  544. //
  545. // Call: CcpMakeOption
  546. //
  547. // Returns: NO_ERROR - Success
  548. // ERROR_BUFFER_TOO_SMALL - Buffer passed in is not large enough.
  549. // ERROR_INVALID_PARAMETER - Option type not recognized.
  550. //
  551. // Description: This is not an entry point, it is an internal procedure called
  552. // to build a particular option.
  553. //
  554. DWORD
  555. CcpMakeOption(
  556. IN CCP_OPTIONS * pOptionValues,
  557. IN DWORD dwOptionType,
  558. IN PPP_OPTION * pSendOption,
  559. IN DWORD cbSendOption
  560. )
  561. {
  562. if ( cbSendOption < PPP_OPTION_HDR_LEN )
  563. {
  564. return( ERROR_BUFFER_TOO_SMALL );
  565. }
  566. pSendOption->Type = (BYTE)dwOptionType;
  567. switch( dwOptionType )
  568. {
  569. case CCP_OPTION_OUI:
  570. pSendOption->Length = (BYTE)( PPP_OPTION_HDR_LEN +
  571. pOptionValues->CompInfo.RCI_MacCompressionValueLength);
  572. if ( pSendOption->Length > cbSendOption )
  573. {
  574. return( ERROR_BUFFER_TOO_SMALL );
  575. }
  576. CopyMemory( pSendOption->Data,
  577. (PBYTE)&(pOptionValues->CompInfo.RCI_Info.RCI_Proprietary),
  578. pSendOption->Length - PPP_OPTION_HDR_LEN );
  579. break;
  580. case CCP_OPTION_MSPPC:
  581. pSendOption->Length = (BYTE)( PPP_OPTION_HDR_LEN + 4 );
  582. if ( pSendOption->Length > cbSendOption )
  583. {
  584. return( ERROR_BUFFER_TOO_SMALL );
  585. }
  586. HostToWireFormat32( pOptionValues->CompInfo.RCI_MSCompressionType,
  587. pSendOption->Data );
  588. break;
  589. default:
  590. //
  591. // Public compression type
  592. //
  593. pSendOption->Length = (BYTE)( PPP_OPTION_HDR_LEN +
  594. pOptionValues->CompInfo.RCI_MacCompressionValueLength);
  595. if ( pSendOption->Length > cbSendOption )
  596. {
  597. return( ERROR_BUFFER_TOO_SMALL );
  598. }
  599. CopyMemory( pSendOption->Data,
  600. (PBYTE)&(pOptionValues->CompInfo.RCI_Info.RCI_Public),
  601. pSendOption->Length - PPP_OPTION_HDR_LEN );
  602. break;
  603. }
  604. return( NO_ERROR );
  605. }
  606. //**
  607. //
  608. // Call: CcpCheckOption
  609. //
  610. // Returns: NO_ERROR - Success
  611. // ERROR_NO_REMOTE_ENCRYPTION
  612. //
  613. // Description: This is not an entry point. Called to check to see if an option
  614. // value is valid and if it is the new value is saved in the
  615. // work buffer. One of the following is returned in *pdwRetCode:
  616. // CONFIG_ACK, CONFIG_NAK, CONFIG_REJ.
  617. //
  618. DWORD
  619. CcpCheckOption(
  620. IN CCPCB * pCcpCb,
  621. IN CCP_SIDE * pCcpSide,
  622. IN PPP_OPTION * pOption,
  623. OUT DWORD * pdwRetCode,
  624. IN BOOL fMakingResult
  625. )
  626. {
  627. DWORD fEncryptionTypes = 0;
  628. BOOL fEncryptionRequested = FALSE;
  629. DWORD dwError = NO_ERROR;
  630. *pdwRetCode = CONFIG_ACK;
  631. switch( pOption->Type )
  632. {
  633. case CCP_OPTION_OUI:
  634. if ( pOption->Length < (PPP_OPTION_HDR_LEN + 4) )
  635. {
  636. dwError = ERROR_PPP_INVALID_PACKET;
  637. break;
  638. }
  639. if ( ( pCcpCb->fDisableCompression ) || ( pCcpCb->fForceEncryption ) )
  640. {
  641. *pdwRetCode = CONFIG_REJ;
  642. break;
  643. }
  644. if ( pCcpSide->Want.CompInfo.RCI_MacCompressionType != CCP_OPTION_OUI )
  645. {
  646. *pdwRetCode = CONFIG_REJ;
  647. break;
  648. }
  649. pCcpSide->Work.CompInfo.RCI_MacCompressionType = CCP_OPTION_OUI;
  650. pCcpSide->Work.CompInfo.RCI_MacCompressionValueLength
  651. = pCcpSide->Want.CompInfo.RCI_MacCompressionValueLength;
  652. pCcpSide->Work.CompInfo.RCI_Info = pCcpSide->Want.CompInfo.RCI_Info;
  653. if ( pOption->Length != PPP_OPTION_HDR_LEN +
  654. pCcpSide->Want.CompInfo.RCI_MacCompressionValueLength )
  655. {
  656. *pdwRetCode = CONFIG_NAK;
  657. break;
  658. }
  659. if ( memcmp( pOption->Data,
  660. (PBYTE)&(pCcpSide->Want.CompInfo.RCI_Info.RCI_Proprietary),
  661. pOption->Length - PPP_OPTION_HDR_LEN ) )
  662. {
  663. *pdwRetCode = CONFIG_NAK;
  664. break;
  665. }
  666. break;
  667. case CCP_OPTION_MSPPC:
  668. if ( pOption->Length != (PPP_OPTION_HDR_LEN + 4) )
  669. {
  670. dwError = ERROR_PPP_INVALID_PACKET;
  671. break;
  672. }
  673. pCcpSide->Work.CompInfo.RCI_MSCompressionType =
  674. WireToHostFormat32( pOption->Data );
  675. //
  676. // If remote guy wants compression but we do not want it, we NAK it
  677. //
  678. if ( ( pCcpCb->fDisableCompression ) &&
  679. ( pCcpSide->Work.CompInfo.RCI_MSCompressionType &
  680. MSTYPE_COMPRESSION ) )
  681. {
  682. pCcpSide->Work.CompInfo.RCI_MSCompressionType &=
  683. ~MSTYPE_COMPRESSION;
  684. TraceCcp("Nak - Compression disabled" );
  685. *pdwRetCode = CONFIG_NAK;
  686. }
  687. //
  688. // If remote side wants do historyless, make sure we support it
  689. //
  690. if (pCcpSide->Work.CompInfo.RCI_MSCompressionType & MSTYPE_HISTORYLESS)
  691. {
  692. if ( !( pCcpSide->Want.CompInfo.RCI_MSCompressionType &
  693. MSTYPE_HISTORYLESS))
  694. {
  695. pCcpSide->Work.CompInfo.RCI_MSCompressionType &=
  696. (~MSTYPE_HISTORYLESS);
  697. *pdwRetCode = CONFIG_NAK;
  698. }
  699. }
  700. //
  701. // Get the encryption types that are to be forced or allowed
  702. //
  703. fEncryptionTypes = pCcpSide->Want.CompInfo.RCI_MSCompressionType &
  704. ( MSTYPE_ENCRYPTION_40F |
  705. MSTYPE_ENCRYPTION_40 |
  706. MSTYPE_ENCRYPTION_56 |
  707. MSTYPE_ENCRYPTION_128 );
  708. //
  709. // Remember if the remote guy wants encryption or not
  710. //
  711. fEncryptionRequested = pCcpSide->Work.CompInfo.RCI_MSCompressionType &
  712. ( MSTYPE_ENCRYPTION_40F |
  713. MSTYPE_ENCRYPTION_40 |
  714. MSTYPE_ENCRYPTION_56 |
  715. MSTYPE_ENCRYPTION_128 );
  716. //
  717. // If we were offered 128 bit encryption
  718. //
  719. if ( pCcpSide->Work.CompInfo.RCI_MSCompressionType &
  720. MSTYPE_ENCRYPTION_128 )
  721. {
  722. //
  723. // If we support it
  724. //
  725. if ( fEncryptionTypes & MSTYPE_ENCRYPTION_128 )
  726. {
  727. //
  728. // If remote side offered any other type
  729. //
  730. if ( pCcpSide->Work.CompInfo.RCI_MSCompressionType &
  731. ( MSTYPE_ENCRYPTION_40F |
  732. MSTYPE_ENCRYPTION_40 |
  733. MSTYPE_ENCRYPTION_56 ) )
  734. {
  735. //
  736. // Turn them off
  737. //
  738. pCcpSide->Work.CompInfo.RCI_MSCompressionType &=
  739. ~( MSTYPE_ENCRYPTION_40F |
  740. MSTYPE_ENCRYPTION_40 |
  741. MSTYPE_ENCRYPTION_56 );
  742. TraceCcp("Nak - Accepting 128 bit");
  743. *pdwRetCode = CONFIG_NAK;
  744. }
  745. }
  746. else
  747. {
  748. //
  749. // we do not support it so turn it off
  750. //
  751. pCcpSide->Work.CompInfo.RCI_MSCompressionType &=
  752. ~MSTYPE_ENCRYPTION_128;
  753. TraceCcp("Nak - 128 bit not supported");
  754. *pdwRetCode = CONFIG_NAK;
  755. }
  756. }
  757. //
  758. // If we were offered 40 variable bit encryption and we support it
  759. //
  760. if ( pCcpSide->Work.CompInfo.RCI_MSCompressionType &
  761. MSTYPE_ENCRYPTION_56 )
  762. {
  763. //
  764. // If we support it
  765. //
  766. if ( fEncryptionTypes & MSTYPE_ENCRYPTION_56 )
  767. {
  768. //
  769. // If remote side offered any other type
  770. //
  771. if ( pCcpSide->Work.CompInfo.RCI_MSCompressionType &
  772. ( MSTYPE_ENCRYPTION_40F |
  773. MSTYPE_ENCRYPTION_40 ) )
  774. {
  775. //
  776. // Turn them off
  777. //
  778. pCcpSide->Work.CompInfo.RCI_MSCompressionType &=
  779. ~( MSTYPE_ENCRYPTION_40F |
  780. MSTYPE_ENCRYPTION_40);
  781. *pdwRetCode = CONFIG_NAK;
  782. }
  783. }
  784. else
  785. {
  786. //
  787. // we do not support it so turn it off
  788. //
  789. pCcpSide->Work.CompInfo.RCI_MSCompressionType &=
  790. ~MSTYPE_ENCRYPTION_56;
  791. *pdwRetCode = CONFIG_NAK;
  792. }
  793. }
  794. //
  795. // If we were offered 40 bit encryption
  796. //
  797. if ( pCcpSide->Work.CompInfo.RCI_MSCompressionType &
  798. MSTYPE_ENCRYPTION_40F )
  799. {
  800. //
  801. // If we support it
  802. //
  803. if ( fEncryptionTypes & MSTYPE_ENCRYPTION_40F )
  804. {
  805. //
  806. // If the remote guy requested any other type
  807. //
  808. if ( pCcpSide->Work.CompInfo.RCI_MSCompressionType &
  809. MSTYPE_ENCRYPTION_40 )
  810. {
  811. //
  812. // Turn them off
  813. //
  814. pCcpSide->Work.CompInfo.RCI_MSCompressionType &=
  815. ~MSTYPE_ENCRYPTION_40;
  816. TraceCcp("Nak - Accepting 40 bit");
  817. *pdwRetCode = CONFIG_NAK;
  818. }
  819. }
  820. else
  821. {
  822. //
  823. // we do not support it so turn it off
  824. //
  825. pCcpSide->Work.CompInfo.RCI_MSCompressionType &=
  826. ~MSTYPE_ENCRYPTION_40F;
  827. TraceCcp("Nak - 40 bit not supported");
  828. *pdwRetCode = CONFIG_NAK;
  829. }
  830. }
  831. //
  832. // If we were offerred legacy 40 bit encryption
  833. //
  834. if ( pCcpSide->Work.CompInfo.RCI_MSCompressionType &
  835. MSTYPE_ENCRYPTION_40 )
  836. {
  837. //
  838. // If we don't support it then turn it off
  839. //
  840. if ( !( fEncryptionTypes & MSTYPE_ENCRYPTION_40 ) )
  841. {
  842. pCcpSide->Work.CompInfo.RCI_MSCompressionType &=
  843. ~MSTYPE_ENCRYPTION_40;
  844. TraceCcp("Nak - legacy 40 bit not supported");
  845. *pdwRetCode = CONFIG_NAK;
  846. }
  847. }
  848. //
  849. // If we have turned all encryption off, or none was offered, but
  850. // we need to force encryption or remote side requested encryption,
  851. // then we we NAK with what we want or what we can do.
  852. //
  853. if ( ( pCcpSide->Work.CompInfo.RCI_MSCompressionType &
  854. ( MSTYPE_ENCRYPTION_40 |
  855. MSTYPE_ENCRYPTION_40F |
  856. MSTYPE_ENCRYPTION_56 |
  857. MSTYPE_ENCRYPTION_128 ) )
  858. == 0 )
  859. {
  860. if ( ( pCcpCb->fForceEncryption ) || ( fEncryptionRequested ) )
  861. {
  862. //
  863. // Make sure we are going to support stuff we NAK
  864. //
  865. if ( fEncryptionTypes != 0 )
  866. {
  867. if ( fMakingResult )
  868. {
  869. //
  870. // If we are NAKing then we can only send one bit.
  871. // Find out the strongest encryption we can NAK with
  872. //
  873. //
  874. // Save the last bit we NAKed with so that in case this
  875. // NAK turns out to be REJECT we can reset to this
  876. // value.
  877. //
  878. pCcpCb->fOldLastEncryptionBitSent =
  879. pCcpCb->fLastEncryptionBitSent;
  880. for(;;)
  881. {
  882. if ( pCcpCb->fLastEncryptionBitSent == 0 )
  883. {
  884. pCcpCb->fLastEncryptionBitSent =
  885. MSTYPE_ENCRYPTION_128;
  886. }
  887. else if ( pCcpCb->fLastEncryptionBitSent ==
  888. MSTYPE_ENCRYPTION_128 )
  889. {
  890. pCcpCb->fLastEncryptionBitSent =
  891. MSTYPE_ENCRYPTION_56;
  892. }
  893. else if ( pCcpCb->fLastEncryptionBitSent ==
  894. MSTYPE_ENCRYPTION_56 )
  895. {
  896. pCcpCb->fLastEncryptionBitSent =
  897. MSTYPE_ENCRYPTION_40F;
  898. }
  899. else if ( pCcpCb->fLastEncryptionBitSent ==
  900. MSTYPE_ENCRYPTION_40F )
  901. {
  902. pCcpCb->fLastEncryptionBitSent =
  903. MSTYPE_ENCRYPTION_40;
  904. }
  905. else
  906. {
  907. //
  908. // Cannot NAK with any encryption
  909. //
  910. pCcpCb->fLastEncryptionBitSent = 0;
  911. if ( !pCcpCb->fForceEncryption )
  912. {
  913. //
  914. // Give up only if we are not forcing
  915. // encryption.
  916. //
  917. *pdwRetCode = CONFIG_NAK;
  918. break;
  919. }
  920. else
  921. {
  922. //
  923. // It is possible that the client did not
  924. // receive our NAK's. Let us restart with
  925. // the strongest encryption we can NAK with
  926. //
  927. }
  928. }
  929. if ( pCcpCb->fLastEncryptionBitSent &
  930. fEncryptionTypes )
  931. {
  932. pCcpSide->Work.CompInfo.RCI_MSCompressionType |=
  933. pCcpCb->fLastEncryptionBitSent;
  934. *pdwRetCode = CONFIG_NAK;
  935. break;
  936. }
  937. }
  938. }
  939. else if ( pCcpCb->fForceEncryption )
  940. {
  941. //
  942. // We require encryption, but there is no common scheme
  943. // that both sides can agree on.
  944. //
  945. return( ERROR_NO_REMOTE_ENCRYPTION );
  946. }
  947. else
  948. {
  949. //
  950. // If we are sending a request then we can send more
  951. // than one bit
  952. //
  953. pCcpSide->Work.CompInfo.RCI_MSCompressionType
  954. |= fEncryptionTypes;
  955. *pdwRetCode = CONFIG_NAK;
  956. }
  957. }
  958. }
  959. }
  960. //
  961. // Turn off any bits that we do not understand
  962. //
  963. if ( pCcpSide->Work.CompInfo.RCI_MSCompressionType &
  964. ~( MSTYPE_ENCRYPTION_40 |
  965. MSTYPE_ENCRYPTION_40F |
  966. MSTYPE_ENCRYPTION_56 |
  967. MSTYPE_ENCRYPTION_128 |
  968. MSTYPE_COMPRESSION |
  969. MSTYPE_HISTORYLESS ) )
  970. {
  971. pCcpSide->Work.CompInfo.RCI_MSCompressionType &=
  972. ( MSTYPE_ENCRYPTION_40 |
  973. MSTYPE_ENCRYPTION_40F |
  974. MSTYPE_ENCRYPTION_56 |
  975. MSTYPE_ENCRYPTION_128 |
  976. MSTYPE_COMPRESSION |
  977. MSTYPE_HISTORYLESS );
  978. TraceCcp("Nak - unknown bits");
  979. *pdwRetCode = CONFIG_NAK;
  980. }
  981. if ( *pdwRetCode == CONFIG_NAK )
  982. {
  983. if ( ( pCcpSide->Work.CompInfo.RCI_MSCompressionType &
  984. ( MSTYPE_ENCRYPTION_40 |
  985. MSTYPE_ENCRYPTION_40F |
  986. MSTYPE_ENCRYPTION_56 |
  987. MSTYPE_ENCRYPTION_128 |
  988. MSTYPE_COMPRESSION ) )
  989. == 0 )
  990. {
  991. TraceCcp("Rej - No bits supported");
  992. *pdwRetCode = CONFIG_REJ;
  993. }
  994. }
  995. break;
  996. default:
  997. if ( pOption->Length < PPP_OPTION_HDR_LEN )
  998. {
  999. dwError = ERROR_PPP_INVALID_PACKET;
  1000. break;
  1001. }
  1002. if ( ( pCcpCb->fDisableCompression ) || ( pCcpCb->fForceEncryption ) )
  1003. {
  1004. *pdwRetCode = CONFIG_REJ;
  1005. break;
  1006. }
  1007. if ( pOption->Type != pCcpSide->Want.CompInfo.RCI_MacCompressionType )
  1008. {
  1009. *pdwRetCode = CONFIG_REJ;
  1010. break;
  1011. }
  1012. pCcpSide->Work.CompInfo.RCI_MacCompressionType
  1013. = pCcpSide->Want.CompInfo.RCI_MacCompressionType;
  1014. pCcpSide->Work.CompInfo.RCI_MacCompressionValueLength
  1015. = pCcpSide->Want.CompInfo.RCI_MacCompressionValueLength;
  1016. pCcpSide->Work.CompInfo.RCI_Info = pCcpSide->Want.CompInfo.RCI_Info;
  1017. if ( pOption->Length != PPP_OPTION_HDR_LEN +
  1018. pCcpSide->Want.CompInfo.RCI_MacCompressionValueLength )
  1019. {
  1020. *pdwRetCode = CONFIG_NAK;
  1021. break;
  1022. }
  1023. if ( memcmp( pOption->Data,
  1024. (PBYTE)&(pCcpSide->Want.CompInfo.RCI_Info.RCI_Public),
  1025. pOption->Length - PPP_OPTION_HDR_LEN ) )
  1026. {
  1027. *pdwRetCode = CONFIG_NAK;
  1028. break;
  1029. }
  1030. }
  1031. return( dwError );
  1032. }
  1033. //**
  1034. //
  1035. // Call: CcpBuildOptionList
  1036. //
  1037. // Returns: NO_ERROR - Success
  1038. // Non-zero returns from CcpMakeOption
  1039. //
  1040. // Description: This is not an entry point. Will build a list of options
  1041. // either for a configure request or a configure result.
  1042. //
  1043. DWORD
  1044. CcpBuildOptionList(
  1045. IN OUT BYTE * pOptions,
  1046. IN OUT DWORD * pcbOptions,
  1047. IN CCP_OPTIONS * CcpOptions,
  1048. IN DWORD Negotiate
  1049. )
  1050. {
  1051. DWORD dwRetCode;
  1052. DWORD cbOptionLength = *pcbOptions;
  1053. if ( Negotiate & CCP_N_OUI )
  1054. {
  1055. if ( ( dwRetCode = CcpMakeOption( CcpOptions,
  1056. CCP_OPTION_OUI,
  1057. (PPP_OPTION *)pOptions,
  1058. cbOptionLength ) ) != NO_ERROR )
  1059. return( dwRetCode );
  1060. cbOptionLength -= ((PPP_OPTION*)pOptions)->Length;
  1061. pOptions += ((PPP_OPTION*)pOptions)->Length;
  1062. }
  1063. if ( Negotiate & CCP_N_PUBLIC )
  1064. {
  1065. if ( ( dwRetCode = CcpMakeOption( CcpOptions,
  1066. CCP_OPTION_MAX,
  1067. (PPP_OPTION *)pOptions,
  1068. cbOptionLength ) ) != NO_ERROR )
  1069. return( dwRetCode );
  1070. cbOptionLength -= ((PPP_OPTION*)pOptions)->Length;
  1071. pOptions += ((PPP_OPTION*)pOptions)->Length;
  1072. }
  1073. if ( Negotiate & CCP_N_MSPPC )
  1074. {
  1075. if ( ( dwRetCode = CcpMakeOption( CcpOptions,
  1076. CCP_OPTION_MSPPC,
  1077. (PPP_OPTION *)pOptions,
  1078. cbOptionLength ) ) != NO_ERROR )
  1079. return( dwRetCode );
  1080. cbOptionLength -= ((PPP_OPTION*)pOptions)->Length;
  1081. pOptions += ((PPP_OPTION*)pOptions)->Length;
  1082. }
  1083. *pcbOptions -= cbOptionLength;
  1084. return( NO_ERROR );
  1085. }
  1086. //**
  1087. //
  1088. // Call: CcpMakeConfigRequest
  1089. //
  1090. // Returns: NO_ERROR - Success
  1091. // Non-zero returns from CcpBuildOptionList
  1092. //
  1093. // Description: This is a entry point that is called to make a confifure
  1094. // request packet.
  1095. //
  1096. DWORD
  1097. CcpMakeConfigRequest(
  1098. IN VOID * pWorkBuffer,
  1099. IN PPP_CONFIG * pSendConfig,
  1100. IN DWORD cbSendConfig
  1101. )
  1102. {
  1103. CCPCB * pCcpCb = (CCPCB*)pWorkBuffer;
  1104. DWORD dwRetCode;
  1105. cbSendConfig -= PPP_CONFIG_HDR_LEN;
  1106. dwRetCode = CcpBuildOptionList( pSendConfig->Data,
  1107. &cbSendConfig,
  1108. &(pCcpCb->Local.Work),
  1109. pCcpCb->Local.Work.Negotiate );
  1110. if ( dwRetCode != NO_ERROR )
  1111. return( dwRetCode );
  1112. pSendConfig->Code = CONFIG_REQ;
  1113. HostToWireFormat16( (WORD)(cbSendConfig + PPP_CONFIG_HDR_LEN),
  1114. pSendConfig->Length);
  1115. return( NO_ERROR );
  1116. }
  1117. //**
  1118. //
  1119. // Call: CcpMakeConfigResult
  1120. //
  1121. // Returns:
  1122. //
  1123. // Description:
  1124. //
  1125. DWORD
  1126. CcpMakeConfigResult(
  1127. IN VOID * pWorkBuffer,
  1128. IN PPP_CONFIG * pRecvConfig,
  1129. OUT PPP_CONFIG * pSendConfig,
  1130. IN DWORD cbSendConfig,
  1131. IN BOOL fRejectNaks
  1132. )
  1133. {
  1134. DWORD OptionListLength;
  1135. DWORD NumOptionsInRequest = 0;
  1136. DWORD dwRetCode;
  1137. DWORD dwError;
  1138. CCPCB * pCcpCb = (CCPCB*)pWorkBuffer;
  1139. DWORD ResultType = CONFIG_ACK;
  1140. PPP_OPTION * pRecvOption = (PPP_OPTION *)(pRecvConfig->Data);
  1141. PPP_OPTION * pSendOption = (PPP_OPTION *)(pSendConfig->Data);
  1142. LONG lSendLength = cbSendConfig - PPP_CONFIG_HDR_LEN;
  1143. LONG lRecvLength = WireToHostFormat16( pRecvConfig->Length )
  1144. - PPP_CONFIG_HDR_LEN;
  1145. //
  1146. // Clear negotiate mask
  1147. //
  1148. pCcpCb->Remote.Work.Negotiate = 0;
  1149. //
  1150. // Process options requested by remote host
  1151. //
  1152. while( lRecvLength > 0 )
  1153. {
  1154. if ( ( lRecvLength -= pRecvOption->Length ) < 0 )
  1155. {
  1156. return( ERROR_PPP_INVALID_PACKET );
  1157. }
  1158. NumOptionsInRequest++;
  1159. dwError = CcpCheckOption(pCcpCb, &(pCcpCb->Remote), pRecvOption,
  1160. &dwRetCode, TRUE);
  1161. if ( NO_ERROR != dwError )
  1162. {
  1163. return( dwError );
  1164. }
  1165. //
  1166. // If we were building an ACK and we got a NAK or reject OR
  1167. // we were building a NAK and we got a reject.
  1168. //
  1169. if ( (( ResultType == CONFIG_ACK ) && ( dwRetCode != CONFIG_ACK )) ||
  1170. (( ResultType == CONFIG_NAK ) && ( dwRetCode == CONFIG_REJ )) )
  1171. {
  1172. ResultType = dwRetCode;
  1173. pSendOption = (PPP_OPTION *)(pSendConfig->Data);
  1174. lSendLength = cbSendConfig - PPP_CONFIG_HDR_LEN;
  1175. }
  1176. //
  1177. // Remember that we processed this option
  1178. //
  1179. if ( ( dwRetCode != CONFIG_REJ ) &&
  1180. ( pRecvOption->Type <= CCP_OPTION_MAX ) )
  1181. {
  1182. switch( pRecvOption->Type )
  1183. {
  1184. case CCP_OPTION_OUI:
  1185. pCcpCb->Remote.Work.Negotiate |= CCP_N_OUI;
  1186. break;
  1187. case CCP_OPTION_MSPPC:
  1188. pCcpCb->Remote.Work.Negotiate |= CCP_N_MSPPC;
  1189. break;
  1190. default:
  1191. pCcpCb->Remote.Work.Negotiate |= CCP_N_PUBLIC;
  1192. break;
  1193. }
  1194. }
  1195. //
  1196. // Add the option to the list.
  1197. //
  1198. if ( dwRetCode == ResultType )
  1199. {
  1200. //
  1201. // If this option is to be rejected, simply copy the
  1202. // rejected option to the send buffer
  1203. //
  1204. if ( ( dwRetCode == CONFIG_REJ ) ||
  1205. ( ( dwRetCode == CONFIG_NAK ) && ( fRejectNaks ) ) )
  1206. {
  1207. CopyMemory( pSendOption, pRecvOption, pRecvOption->Length );
  1208. lSendLength -= pSendOption->Length;
  1209. pSendOption = (PPP_OPTION *)
  1210. ( (BYTE *)pSendOption + pSendOption->Length );
  1211. }
  1212. }
  1213. pRecvOption = (PPP_OPTION *)((BYTE*)pRecvOption + pRecvOption->Length);
  1214. }
  1215. //
  1216. // If this was an NAK and we have cannot send any more NAKS then we
  1217. // make this a REJECT packet
  1218. //
  1219. if ( ( ResultType == CONFIG_NAK ) && fRejectNaks )
  1220. pSendConfig->Code = CONFIG_REJ;
  1221. else
  1222. pSendConfig->Code = (BYTE)ResultType;
  1223. //
  1224. // Remote wants no options, accept this
  1225. //
  1226. if ( NumOptionsInRequest == 0 )
  1227. {
  1228. //
  1229. // Accept no options only if we are not forcing encryption
  1230. //
  1231. if ( pCcpCb->fForceEncryption )
  1232. {
  1233. NumOptionsInRequest = 1;
  1234. pCcpCb->Remote.Work.Negotiate = CCP_N_MSPPC;
  1235. ResultType = CONFIG_NAK;
  1236. }
  1237. }
  1238. //
  1239. // If we are responding to the request with a NAK or an ACK then we make
  1240. // that we choose only one option.
  1241. //
  1242. if ( ( ( ResultType == CONFIG_ACK ) || ( ResultType == CONFIG_NAK ) )
  1243. && ( NumOptionsInRequest > 0 ) )
  1244. {
  1245. if ( pCcpCb->Remote.Work.Negotiate & CCP_N_MSPPC )
  1246. {
  1247. pCcpCb->Remote.Work.Negotiate = CCP_N_MSPPC;
  1248. if ( ( dwRetCode = CcpMakeOption( &(pCcpCb->Remote.Work),
  1249. CCP_OPTION_MSPPC,
  1250. pSendOption,
  1251. lSendLength ) ) != NO_ERROR )
  1252. return( dwRetCode );
  1253. }
  1254. else if ( pCcpCb->Remote.Work.Negotiate & CCP_N_OUI )
  1255. {
  1256. pCcpCb->Remote.Work.Negotiate = CCP_N_OUI;
  1257. if ( ( dwRetCode = CcpMakeOption( &(pCcpCb->Remote.Work),
  1258. CCP_OPTION_OUI,
  1259. pSendOption,
  1260. lSendLength ) ) != NO_ERROR )
  1261. return( dwRetCode );
  1262. }
  1263. else
  1264. {
  1265. pCcpCb->Remote.Work.Negotiate = CCP_N_PUBLIC;
  1266. if ( ( dwRetCode = CcpMakeOption( &(pCcpCb->Remote.Work),
  1267. CCP_OPTION_MAX,
  1268. pSendOption,
  1269. lSendLength ) ) != NO_ERROR )
  1270. return( dwRetCode );
  1271. }
  1272. if ( ( NumOptionsInRequest > 1 ) && ( ResultType == CONFIG_ACK ) )
  1273. {
  1274. pSendConfig->Code = CONFIG_NAK;
  1275. }
  1276. else
  1277. {
  1278. pSendConfig->Code = (BYTE)ResultType;
  1279. }
  1280. lSendLength -= pSendOption->Length;
  1281. }
  1282. //
  1283. // If we are rejecting then we reset the current value to the old value
  1284. //
  1285. if ( pSendConfig->Code == CONFIG_REJ )
  1286. {
  1287. pCcpCb->fLastEncryptionBitSent = pCcpCb->fOldLastEncryptionBitSent;
  1288. }
  1289. else
  1290. {
  1291. pCcpCb->fOldLastEncryptionBitSent = pCcpCb->fLastEncryptionBitSent;
  1292. }
  1293. HostToWireFormat16( (WORD)(cbSendConfig - lSendLength),
  1294. pSendConfig->Length );
  1295. return( NO_ERROR );
  1296. }
  1297. //**
  1298. //
  1299. // Call: CcpConfigAckReceived
  1300. //
  1301. // Returns:
  1302. //
  1303. // Description:
  1304. //
  1305. DWORD
  1306. CcpConfigAckReceived(
  1307. IN VOID * pWorkBuffer,
  1308. IN PPP_CONFIG * pRecvConfig
  1309. )
  1310. {
  1311. DWORD dwRetCode;
  1312. BYTE ConfigReqSent[500];
  1313. CCPCB * pCcpCb = (CCPCB *)pWorkBuffer;
  1314. DWORD cbConfigReqSent = sizeof( ConfigReqSent );
  1315. DWORD dwLength = WireToHostFormat16( pRecvConfig->Length )
  1316. - PPP_CONFIG_HDR_LEN;
  1317. //
  1318. // Get a copy of last request we sent
  1319. //
  1320. dwRetCode = CcpBuildOptionList( ConfigReqSent,
  1321. &cbConfigReqSent,
  1322. &(pCcpCb->Local.Work),
  1323. pCcpCb->Local.Work.Negotiate );
  1324. if ( dwRetCode != NO_ERROR )
  1325. {
  1326. return( dwRetCode );
  1327. }
  1328. //
  1329. // Overall buffer length should match
  1330. //
  1331. if ( dwLength != cbConfigReqSent )
  1332. {
  1333. return( ERROR_PPP_INVALID_PACKET );
  1334. }
  1335. //
  1336. // Each byte should match
  1337. //
  1338. if ( memcmp( ConfigReqSent, pRecvConfig->Data, dwLength ) != 0 )
  1339. {
  1340. return( ERROR_PPP_INVALID_PACKET );
  1341. }
  1342. return( NO_ERROR );
  1343. }
  1344. //**
  1345. //
  1346. // Call: CcpConfigNakReceived
  1347. //
  1348. // Returns:
  1349. //
  1350. // Description:
  1351. //
  1352. DWORD
  1353. CcpConfigNakReceived(
  1354. IN VOID * pWorkBuffer,
  1355. IN PPP_CONFIG * pRecvConfig
  1356. )
  1357. {
  1358. DWORD fAcceptableOptions = 0;
  1359. DWORD dwResult;
  1360. DWORD dwError;
  1361. CCPCB * pCcpCb = (CCPCB *)pWorkBuffer;
  1362. PPP_OPTION * pOption = (PPP_OPTION*)(pRecvConfig->Data);
  1363. DWORD dwLastOption = 0;
  1364. LONG lcbRecvConfig = WireToHostFormat16( pRecvConfig->Length )
  1365. - PPP_CONFIG_HDR_LEN;
  1366. //
  1367. // First, process in order. Then, process extra "important" options
  1368. //
  1369. while ( lcbRecvConfig > 0 )
  1370. {
  1371. if ( ( lcbRecvConfig -= pOption->Length ) < 0 )
  1372. {
  1373. return( ERROR_PPP_INVALID_PACKET );
  1374. }
  1375. //
  1376. // Our requests are always sent out in order of increasing option type
  1377. // values.
  1378. //
  1379. if ( pOption->Type < dwLastOption )
  1380. {
  1381. return( ERROR_PPP_INVALID_PACKET );
  1382. }
  1383. dwLastOption = pOption->Type;
  1384. dwError = CcpCheckOption( pCcpCb, &(pCcpCb->Local), pOption,
  1385. &dwResult, FALSE);
  1386. if ( NO_ERROR != dwError )
  1387. {
  1388. return( dwError );
  1389. }
  1390. //
  1391. // Update the negotiation status. If we cannot accept this option,
  1392. // then we will not send it again.
  1393. //
  1394. switch( pOption->Type )
  1395. {
  1396. case CCP_OPTION_OUI:
  1397. if ( dwResult == CONFIG_REJ )
  1398. {
  1399. pCcpCb->Local.Work.Negotiate &= ~CCP_N_OUI;
  1400. }
  1401. if ( dwResult == CONFIG_ACK )
  1402. {
  1403. fAcceptableOptions |= CCP_N_OUI;
  1404. }
  1405. break;
  1406. case CCP_OPTION_MSPPC:
  1407. if ( dwResult == CONFIG_REJ )
  1408. {
  1409. pCcpCb->Local.Work.Negotiate &= ~CCP_N_MSPPC;
  1410. }
  1411. if ( dwResult == CONFIG_ACK )
  1412. {
  1413. fAcceptableOptions |= CCP_N_MSPPC;
  1414. }
  1415. break;
  1416. default:
  1417. if ( dwResult == CONFIG_REJ )
  1418. {
  1419. pCcpCb->Local.Work.Negotiate &= ~CCP_N_PUBLIC;
  1420. }
  1421. if ( dwResult == CONFIG_ACK )
  1422. {
  1423. fAcceptableOptions |= CCP_N_PUBLIC;
  1424. }
  1425. break;
  1426. }
  1427. pOption = (PPP_OPTION *)( (BYTE *)pOption + pOption->Length );
  1428. }
  1429. if ( pCcpCb->Local.Work.Negotiate == 0 )
  1430. {
  1431. if ( pCcpCb->fForceEncryption )
  1432. {
  1433. fAcceptableOptions = CCP_N_MSPPC;
  1434. }
  1435. else
  1436. {
  1437. fAcceptableOptions = 0;
  1438. }
  1439. }
  1440. //
  1441. // If there was more than one option that was acceptable give
  1442. // preference to OUI, then to PUBLIC, then to MSPPC
  1443. //
  1444. if ( fAcceptableOptions & CCP_N_OUI )
  1445. {
  1446. pCcpCb->Local.Work.Negotiate = CCP_N_OUI;
  1447. }
  1448. else if ( fAcceptableOptions & CCP_N_PUBLIC )
  1449. {
  1450. pCcpCb->Local.Work.Negotiate = CCP_N_PUBLIC;
  1451. }
  1452. else if ( fAcceptableOptions & CCP_N_MSPPC )
  1453. {
  1454. pCcpCb->Local.Work.Negotiate = CCP_N_MSPPC;
  1455. }
  1456. return( NO_ERROR );
  1457. }
  1458. //**
  1459. //
  1460. // Call: CcpConfigRejReceived
  1461. //
  1462. // Returns:
  1463. //
  1464. // Description:
  1465. //
  1466. DWORD
  1467. CcpConfigRejReceived(
  1468. IN VOID * pWorkBuffer,
  1469. IN PPP_CONFIG * pRecvConfig
  1470. )
  1471. {
  1472. DWORD dwRetCode;
  1473. CCPCB * pCcpCb = (CCPCB *)pWorkBuffer;
  1474. PPP_OPTION * pOption = (PPP_OPTION*)(pRecvConfig->Data);
  1475. DWORD dwLastOption = 0;
  1476. BYTE ReqOption[500];
  1477. LONG lcbRecvConfig = WireToHostFormat16( pRecvConfig->Length )
  1478. - PPP_CONFIG_HDR_LEN;
  1479. //
  1480. // Process in order, checking for errors
  1481. //
  1482. while ( lcbRecvConfig > 0 )
  1483. {
  1484. if ( ( lcbRecvConfig -= pOption->Length ) < 0 )
  1485. {
  1486. return( ERROR_PPP_INVALID_PACKET );
  1487. }
  1488. //
  1489. // The option should not have been modified in any way
  1490. //
  1491. if ( ( dwRetCode = CcpMakeOption( &(pCcpCb->Local.Work),
  1492. pOption->Type,
  1493. (PPP_OPTION *)ReqOption,
  1494. sizeof( ReqOption ) ) ) != NO_ERROR )
  1495. return( dwRetCode );
  1496. if ( memcmp( ReqOption, pOption, pOption->Length ) != 0 )
  1497. {
  1498. return( ERROR_PPP_INVALID_PACKET );
  1499. }
  1500. dwLastOption = pOption->Type;
  1501. //
  1502. // The next configure request should not contain this option
  1503. //
  1504. if ( pOption->Type <= CCP_OPTION_MAX )
  1505. {
  1506. switch( pOption->Type )
  1507. {
  1508. case CCP_OPTION_OUI:
  1509. pCcpCb->Local.Work.Negotiate &= ~CCP_N_OUI;
  1510. break;
  1511. case CCP_OPTION_MSPPC:
  1512. pCcpCb->Local.Work.Negotiate &= ~CCP_N_MSPPC;
  1513. break;
  1514. default:
  1515. pCcpCb->Local.Work.Negotiate &= ~CCP_N_PUBLIC;
  1516. break;
  1517. }
  1518. }
  1519. pOption = (PPP_OPTION *)( (BYTE *)pOption + pOption->Length );
  1520. }
  1521. if ( pCcpCb->Local.Work.Negotiate == 0 )
  1522. {
  1523. return( ERROR_PPP_NOT_CONVERGING );
  1524. }
  1525. return( NO_ERROR );
  1526. }
  1527. //**
  1528. //
  1529. // Call: CcpThisLayerStarted
  1530. //
  1531. // Returns:
  1532. //
  1533. // Description:
  1534. //
  1535. DWORD
  1536. CcpThisLayerStarted(
  1537. IN VOID * pWorkBuffer
  1538. )
  1539. {
  1540. return( NO_ERROR );
  1541. }
  1542. //**
  1543. //
  1544. // Call: CcpThisLayerFinished
  1545. //
  1546. // Returns:
  1547. //
  1548. // Description:
  1549. //
  1550. DWORD
  1551. CcpThisLayerFinished(
  1552. IN VOID * pWorkBuffer
  1553. )
  1554. {
  1555. return( NO_ERROR );
  1556. }
  1557. //**
  1558. //
  1559. // Call: CcpThisLayerUp
  1560. //
  1561. // Returns: None
  1562. //
  1563. // Description: Sets the framing parameters to what was negotiated.
  1564. //
  1565. DWORD
  1566. CcpThisLayerUp(
  1567. IN VOID * pWorkBuffer
  1568. )
  1569. {
  1570. DWORD dwRetCode = NO_ERROR;
  1571. CCPCB * pCcpCb = (CCPCB *)pWorkBuffer;
  1572. RAS_COMPRESSION_INFO RasCompInfoSend;
  1573. RAS_COMPRESSION_INFO RasCompInfoRecv;
  1574. if ( pCcpCb->Local.Work.Negotiate == CCP_N_MSPPC )
  1575. {
  1576. TraceCcp("CCP Send MSPPC bits negotiated = 0x%x",
  1577. pCcpCb->Local.Work.CompInfo.RCI_MSCompressionType );
  1578. pCcpCb->Local.Work.CompInfo.RCI_MacCompressionType = CCP_OPTION_MAX + 1;
  1579. }
  1580. else if ( pCcpCb->Local.Work.Negotiate == CCP_N_PUBLIC )
  1581. {
  1582. TraceCcp("CCP Send PUBLIC");
  1583. pCcpCb->Local.Work.CompInfo.RCI_MSCompressionType = 0;
  1584. }
  1585. else if ( pCcpCb->Local.Work.Negotiate == CCP_N_OUI )
  1586. {
  1587. TraceCcp("CCP Send OUI");
  1588. pCcpCb->Local.Work.CompInfo.RCI_MSCompressionType = 0;
  1589. }
  1590. if ( pCcpCb->Remote.Work.Negotiate == CCP_N_MSPPC )
  1591. {
  1592. TraceCcp("CCP Recv MSPPC bits negotiated = 0x%x",
  1593. pCcpCb->Remote.Work.CompInfo.RCI_MSCompressionType );
  1594. pCcpCb->Remote.Work.CompInfo.RCI_MacCompressionType = CCP_OPTION_MAX+1;
  1595. }
  1596. else if ( pCcpCb->Remote.Work.Negotiate == CCP_N_PUBLIC )
  1597. {
  1598. TraceCcp("CCP Recv PUBLIC");
  1599. pCcpCb->Remote.Work.CompInfo.RCI_MSCompressionType = 0;
  1600. }
  1601. else if ( pCcpCb->Remote.Work.Negotiate == CCP_N_OUI )
  1602. {
  1603. TraceCcp("CCP Recv OUI");
  1604. pCcpCb->Remote.Work.CompInfo.RCI_MSCompressionType = 0;
  1605. }
  1606. dwRetCode = RasCompressionGetInfo( pCcpCb->hPort,
  1607. &RasCompInfoSend,
  1608. &RasCompInfoRecv );
  1609. if ( dwRetCode != NO_ERROR )
  1610. {
  1611. return( dwRetCode );
  1612. }
  1613. CopyMemory( pCcpCb->Local.Work.CompInfo.RCI_LMSessionKey,
  1614. RasCompInfoSend.RCI_LMSessionKey,
  1615. MAX_SESSIONKEY_SIZE );
  1616. CopyMemory( pCcpCb->Local.Work.CompInfo.RCI_UserSessionKey,
  1617. RasCompInfoSend.RCI_UserSessionKey,
  1618. MAX_USERSESSIONKEY_SIZE );
  1619. CopyMemory( pCcpCb->Local.Work.CompInfo.RCI_Challenge,
  1620. RasCompInfoSend.RCI_Challenge,
  1621. MAX_CHALLENGE_SIZE );
  1622. CopyMemory( pCcpCb->Local.Work.CompInfo.RCI_NTResponse,
  1623. RasCompInfoSend.RCI_NTResponse,
  1624. MAX_NT_RESPONSE_SIZE );
  1625. pCcpCb->Local.Work.CompInfo.RCI_Flags = CCP_SET_COMPTYPE;
  1626. CopyMemory( pCcpCb->Remote.Work.CompInfo.RCI_LMSessionKey,
  1627. RasCompInfoRecv.RCI_LMSessionKey,
  1628. MAX_SESSIONKEY_SIZE );
  1629. CopyMemory( pCcpCb->Remote.Work.CompInfo.RCI_UserSessionKey,
  1630. RasCompInfoRecv.RCI_UserSessionKey,
  1631. MAX_USERSESSIONKEY_SIZE );
  1632. CopyMemory( pCcpCb->Remote.Work.CompInfo.RCI_Challenge,
  1633. RasCompInfoRecv.RCI_Challenge,
  1634. MAX_CHALLENGE_SIZE );
  1635. CopyMemory( pCcpCb->Remote.Work.CompInfo.RCI_NTResponse,
  1636. RasCompInfoRecv.RCI_NTResponse,
  1637. MAX_NT_RESPONSE_SIZE );
  1638. pCcpCb->Remote.Work.CompInfo.RCI_Flags = CCP_SET_COMPTYPE;
  1639. if ( pCcpCb->fServer )
  1640. {
  1641. pCcpCb->Local.Work.CompInfo.RCI_Flags |= CCP_IS_SERVER;
  1642. pCcpCb->Remote.Work.CompInfo.RCI_Flags |= CCP_IS_SERVER;
  1643. }
  1644. dwRetCode = RasCompressionSetInfo( pCcpCb->hPort,
  1645. &(pCcpCb->Local.Work.CompInfo),
  1646. &(pCcpCb->Remote.Work.CompInfo) );
  1647. return( dwRetCode );
  1648. }
  1649. //**
  1650. //
  1651. // Call: CcpThisLayerDown
  1652. //
  1653. // Returns: NO_ERROR - Success
  1654. // Non-zero return from RasPortSetFraming - Failure
  1655. //
  1656. // Description: Simply sets the framing parameters to the default values,
  1657. // ie. ACCM = 0xFFFFFFFF, everything else is zeros.
  1658. //
  1659. DWORD
  1660. CcpThisLayerDown(
  1661. IN VOID * pWorkBuffer
  1662. )
  1663. {
  1664. CCPCB * pCcpCb = (CCPCB *)pWorkBuffer;
  1665. RAS_COMPRESSION_INFO CompInfo;
  1666. ZeroMemory( &CompInfo, sizeof( CompInfo ) );
  1667. CompInfo.RCI_Flags = CCP_SET_COMPTYPE;
  1668. CompInfo.RCI_MSCompressionType = 0;
  1669. CompInfo.RCI_MacCompressionType = CCP_OPTION_MAX + 1;
  1670. CopyMemory( CompInfo.RCI_LMSessionKey,
  1671. pCcpCb->Local.Want.CompInfo.RCI_LMSessionKey,
  1672. sizeof( CompInfo.RCI_LMSessionKey ) );
  1673. CopyMemory( CompInfo.RCI_UserSessionKey,
  1674. pCcpCb->Local.Want.CompInfo.RCI_UserSessionKey,
  1675. sizeof( CompInfo.RCI_UserSessionKey ) );
  1676. CopyMemory( CompInfo.RCI_Challenge,
  1677. pCcpCb->Local.Want.CompInfo.RCI_Challenge,
  1678. sizeof( CompInfo.RCI_Challenge ) );
  1679. if ( pCcpCb->fForceEncryption )
  1680. {
  1681. pCcpCb->Local.Work.CompInfo.RCI_Flags |= CCP_PAUSE_DATA;
  1682. pCcpCb->Remote.Work.CompInfo.RCI_Flags |= CCP_PAUSE_DATA;
  1683. }
  1684. RasCompressionSetInfo( pCcpCb->hPort, &CompInfo, &CompInfo );
  1685. return( NO_ERROR );
  1686. }
  1687. //**
  1688. //
  1689. // Call: CcpGetNegotiatedInfo
  1690. //
  1691. // Returns: NO_ERROR - Success
  1692. // Non-zero returns - Failure
  1693. //
  1694. // Description: Will return the type of compression and associated date
  1695. // negotiated for both directions.
  1696. //
  1697. DWORD
  1698. CcpGetNegotiatedInfo(
  1699. IN VOID * pWorkBuffer,
  1700. OUT PPP_CCP_RESULT * pCcpResult
  1701. )
  1702. {
  1703. CCPCB * pCcpCb = (CCPCB *)pWorkBuffer;
  1704. if ( pCcpCb->Local.Work.Negotiate == CCP_N_MSPPC )
  1705. {
  1706. pCcpResult->dwSendProtocol = CCP_OPTION_MSPPC;
  1707. pCcpResult->dwSendProtocolData =
  1708. pCcpCb->Local.Work.CompInfo.RCI_MSCompressionType;
  1709. }
  1710. else
  1711. {
  1712. pCcpResult->dwSendProtocol =
  1713. pCcpCb->Local.Work.CompInfo.RCI_MacCompressionType;
  1714. }
  1715. if ( pCcpCb->Remote.Work.Negotiate == CCP_N_MSPPC )
  1716. {
  1717. pCcpResult->dwReceiveProtocol = CCP_OPTION_MSPPC;
  1718. pCcpResult->dwReceiveProtocolData =
  1719. pCcpCb->Remote.Work.CompInfo.RCI_MSCompressionType;
  1720. }
  1721. else
  1722. {
  1723. pCcpResult->dwReceiveProtocol =
  1724. pCcpCb->Remote.Work.CompInfo.RCI_MacCompressionType;
  1725. }
  1726. return( NO_ERROR );
  1727. }
  1728. //**
  1729. //
  1730. // Call: CcpGetInfo
  1731. //
  1732. // Returns: NO_ERROR - Success
  1733. // ERROR_INVALID_PARAMETER - Protocol id is unrecogized
  1734. //
  1735. // Description: This entry point is called for get all information for the
  1736. // control protocol in this module.
  1737. //
  1738. DWORD
  1739. CcpGetInfo(
  1740. IN DWORD dwProtocolId,
  1741. OUT PPPCP_INFO* pCpInfo
  1742. )
  1743. {
  1744. if ( dwProtocolId != PPP_CCP_PROTOCOL )
  1745. {
  1746. return( ERROR_INVALID_PARAMETER );
  1747. }
  1748. ZeroMemory( pCpInfo, sizeof( PPPCP_INFO ) );
  1749. pCpInfo->Protocol = PPP_CCP_PROTOCOL;
  1750. lstrcpy(pCpInfo->SzProtocolName, "CCP");
  1751. pCpInfo->Recognize = CODE_REJ + 1;
  1752. pCpInfo->RasCpInit = CcpInit;
  1753. pCpInfo->RasCpBegin = CcpBegin;
  1754. pCpInfo->RasCpEnd = CcpEnd;
  1755. pCpInfo->RasCpReset = CcpReset;
  1756. pCpInfo->RasCpThisLayerStarted = CcpThisLayerStarted;
  1757. pCpInfo->RasCpThisLayerFinished = CcpThisLayerFinished;
  1758. pCpInfo->RasCpThisLayerUp = CcpThisLayerUp;
  1759. pCpInfo->RasCpThisLayerDown = CcpThisLayerDown;
  1760. pCpInfo->RasCpMakeConfigRequest = CcpMakeConfigRequest;
  1761. pCpInfo->RasCpMakeConfigResult = CcpMakeConfigResult;
  1762. pCpInfo->RasCpConfigAckReceived = CcpConfigAckReceived;
  1763. pCpInfo->RasCpConfigNakReceived = CcpConfigNakReceived;
  1764. pCpInfo->RasCpConfigRejReceived = CcpConfigRejReceived;
  1765. pCpInfo->RasCpGetNegotiatedInfo = CcpGetNegotiatedInfo;
  1766. return( NO_ERROR );
  1767. }