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.

2491 lines
67 KiB

  1. /********************************************************************/
  2. /** Copyright(c) 1989 Microsoft Corporation. **/
  3. /********************************************************************/
  4. //***
  5. //
  6. // Filename: lcp.c
  7. //
  8. // Description: Contains entry points to configure LCP.
  9. //
  10. // History:
  11. // Nov 11,1993. NarenG Created original version.
  12. //
  13. //
  14. #include <nt.h>
  15. #include <ntrtl.h>
  16. #include <nturtl.h> // needed for winbase.h
  17. #include <windows.h> // Win32 base API's
  18. #include <stdlib.h>
  19. #include <string.h>
  20. #include <wchar.h>
  21. #include <lmcons.h>
  22. #include <raserror.h>
  23. #include <mprerror.h>
  24. #include <rasman.h>
  25. #include <rasppp.h>
  26. #include <pppcp.h>
  27. #include <ppp.h>
  28. #include <smaction.h>
  29. #include <lcp.h>
  30. #include <timer.h>
  31. #include <util.h>
  32. #include <worker.h>
  33. //
  34. // Default values
  35. //
  36. const static LCP_OPTIONS LcpDefault =
  37. {
  38. 0, // Negotiation flags
  39. LCP_DEFAULT_MRU, // Default value for MRU
  40. 0xFFFFFFFF, // Default ACCM value.
  41. 0, // no authentication ( for client )
  42. 0, // no authentication data. ( for client )
  43. NULL, // no authentication data. ( for client )
  44. 0, // Magic Number.
  45. FALSE, // Protocol field compression.
  46. FALSE, // Address and Contorl-Field Compression.
  47. 0, // Callback Operation message field
  48. LCP_DEFAULT_MRU, // Default value for MRRU == MRU according to RFC1717
  49. 0, // No short sequencing
  50. 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, // No endpoint discriminator
  51. 0, // Length of Endpoint Discriminator
  52. 0 // Link Discriminator (for BAP/BACP)
  53. };
  54. //
  55. // Accept anything we understand in the NAK and in a REQ from a remote host
  56. //
  57. static DWORD LcpNegotiate = LCP_N_MRU | LCP_N_ACCM | LCP_N_MAGIC |
  58. LCP_N_PFC | LCP_N_ACFC;
  59. static DWORD SizeOfOption[] =
  60. {
  61. 0, // unused
  62. PPP_OPTION_HDR_LEN + 2, // MRU
  63. PPP_OPTION_HDR_LEN + 4, // ACCM
  64. PPP_OPTION_HDR_LEN + 2, // authentication
  65. 0, // Unused.
  66. PPP_OPTION_HDR_LEN + 4, // magic number
  67. 0, // Reserved, unused
  68. PPP_OPTION_HDR_LEN + 0, // Protocol compression
  69. PPP_OPTION_HDR_LEN + 0, // Address/Control compression
  70. 0, // Unused
  71. 0, // Unused
  72. 0, // Unused
  73. 0, // Unused
  74. PPP_OPTION_HDR_LEN + 1, // Callback
  75. 0, // Unused
  76. 0, // Unused
  77. 0, // Unused
  78. PPP_OPTION_HDR_LEN + 2, // MRRU
  79. PPP_OPTION_HDR_LEN + 0, // Short Sequence Header Format
  80. PPP_OPTION_HDR_LEN, // Endpoint Discriminator
  81. 0, // Unused
  82. 0, // Unused
  83. 0, // Unused
  84. PPP_OPTION_HDR_LEN + 2 // Link Discriminator (for BAP/BACP)
  85. };
  86. WORD WLinkDiscriminator = 0; // Next Link Discriminator to use
  87. BYTE BCount = 0; // To make EndpointDiscriminator different
  88. //**
  89. //
  90. // Call: MakeAuthProtocolOption
  91. //
  92. // Returns: NO_ERROR - Success
  93. // Non-zero returns - Failure
  94. //
  95. // Description: Given a certain authentication protocol, will construct the
  96. // configuration option for it.
  97. //
  98. DWORD
  99. MakeAuthProtocolOption(
  100. IN LCP_SIDE * pLcpSide
  101. )
  102. {
  103. switch( pLcpSide->fLastAPTried )
  104. {
  105. case LCP_AP_EAP:
  106. pLcpSide->Work.AP = PPP_EAP_PROTOCOL;
  107. if ( pLcpSide->Work.APDataSize != 0 )
  108. {
  109. pLcpSide->Work.APDataSize = 0;
  110. if ( pLcpSide->Work.pAPData != NULL )
  111. {
  112. LOCAL_FREE( pLcpSide->Work.pAPData );
  113. pLcpSide->Work.pAPData = NULL;
  114. }
  115. }
  116. break;
  117. case LCP_AP_CHAP_MS:
  118. case LCP_AP_CHAP_MS_NEW:
  119. default:
  120. pLcpSide->Work.AP = PPP_CHAP_PROTOCOL;
  121. if ( pLcpSide->Work.APDataSize != 1 )
  122. {
  123. pLcpSide->Work.APDataSize = 1;
  124. if ( NULL != pLcpSide->Work.pAPData )
  125. {
  126. LOCAL_FREE( pLcpSide->Work.pAPData );
  127. pLcpSide->Work.pAPData = NULL;
  128. }
  129. pLcpSide->Work.pAPData = (PBYTE)LOCAL_ALLOC(
  130. LPTR,
  131. pLcpSide->Work.APDataSize );
  132. if ( pLcpSide->Work.pAPData == NULL )
  133. {
  134. pLcpSide->Work.APDataSize = 0;
  135. return( GetLastError() );
  136. }
  137. }
  138. if ( pLcpSide->fLastAPTried == LCP_AP_CHAP_MS_NEW )
  139. {
  140. *(pLcpSide->Work.pAPData) = PPP_CHAP_DIGEST_MSEXT_NEW;
  141. }
  142. else
  143. {
  144. *(pLcpSide->Work.pAPData) = PPP_CHAP_DIGEST_MSEXT;
  145. }
  146. break;
  147. case LCP_AP_CHAP_MD5:
  148. pLcpSide->Work.AP = PPP_CHAP_PROTOCOL;
  149. if ( pLcpSide->Work.APDataSize != 1 )
  150. {
  151. pLcpSide->Work.APDataSize = 1;
  152. if ( NULL != pLcpSide->Work.pAPData )
  153. {
  154. LOCAL_FREE( pLcpSide->Work.pAPData );
  155. pLcpSide->Work.pAPData = NULL;
  156. }
  157. pLcpSide->Work.pAPData = (PBYTE)LOCAL_ALLOC(
  158. LPTR,
  159. pLcpSide->Work.APDataSize );
  160. if ( pLcpSide->Work.pAPData == NULL )
  161. {
  162. pLcpSide->Work.APDataSize = 0;
  163. return( GetLastError() );
  164. }
  165. }
  166. *(pLcpSide->Work.pAPData) = PPP_CHAP_DIGEST_MD5;
  167. break;
  168. case LCP_AP_SPAP_NEW:
  169. pLcpSide->Work.AP = PPP_SPAP_NEW_PROTOCOL;
  170. if ( pLcpSide->Work.APDataSize != 4 )
  171. {
  172. pLcpSide->Work.APDataSize = 4;
  173. if ( NULL != pLcpSide->Work.pAPData )
  174. {
  175. LOCAL_FREE( pLcpSide->Work.pAPData );
  176. pLcpSide->Work.pAPData = NULL;
  177. }
  178. pLcpSide->Work.pAPData = (PBYTE)LOCAL_ALLOC(
  179. LPTR,
  180. pLcpSide->Work.APDataSize );
  181. if ( pLcpSide->Work.pAPData == NULL )
  182. {
  183. pLcpSide->Work.APDataSize = 0;
  184. return( GetLastError() );
  185. }
  186. }
  187. HostToWireFormat32( LCP_SPAP_VERSION, pLcpSide->Work.pAPData );
  188. break;
  189. case LCP_AP_PAP:
  190. pLcpSide->Work.AP = PPP_PAP_PROTOCOL;
  191. if ( pLcpSide->Work.APDataSize != 0 )
  192. {
  193. pLcpSide->Work.APDataSize = 0;
  194. if ( pLcpSide->Work.pAPData != NULL )
  195. {
  196. LOCAL_FREE( pLcpSide->Work.pAPData );
  197. pLcpSide->Work.pAPData = NULL;
  198. }
  199. }
  200. break;
  201. }
  202. return( NO_ERROR );
  203. }
  204. //**
  205. //
  206. // Call: LcpBegin
  207. //
  208. // Returns: NO_ERROR - Success
  209. // non-zero error - Failure
  210. //
  211. //
  212. // Description: Called once before any other call to LCP is made. Allocate
  213. // a work buffer and initialize it.
  214. //
  215. DWORD
  216. LcpBegin(
  217. IN OUT VOID** ppWorkBuf,
  218. IN VOID* pInfo
  219. )
  220. {
  221. LCPCB * pLcpCb;
  222. RAS_FRAMING_CAPABILITIES RasFramingCapabilities;
  223. DWORD dwRetCode;
  224. DWORD dwIndex;
  225. PPPCP_INIT * pPppCpInit;
  226. *ppWorkBuf = LOCAL_ALLOC( LPTR, sizeof( LCPCB ) );
  227. if ( *ppWorkBuf == NULL )
  228. {
  229. return( GetLastError() );
  230. }
  231. pLcpCb = (LCPCB *)*ppWorkBuf;
  232. pPppCpInit = (PPPCP_INIT *)pInfo;
  233. pLcpCb->fServer = pPppCpInit->fServer;
  234. pLcpCb->hPort = pPppCpInit->hPort;
  235. pLcpCb->PppConfigInfo = pPppCpInit->PppConfigInfo;;
  236. pLcpCb->fRouter = ( pPppCpInit->IfType ==
  237. ROUTER_IF_TYPE_FULL_ROUTER );
  238. pLcpCb->dwMagicNumberFailureCount = 0;
  239. pLcpCb->dwMRUFailureCount = 2;
  240. //
  241. // Check to see if we need to override the Negotiate Multi Link
  242. // send by the caller
  243. // BugID: WINSE 17061 Windows Bugs: 347562
  244. if ( PppConfigInfo.dwDontNegotiateMultiLinkOnSingleLink )
  245. {
  246. //remove NegotiateMultiLink from config info
  247. PppLog( 2, "Removing NegotiateMultilink due to registry override" );
  248. pLcpCb->PppConfigInfo.dwConfigMask &= ~PPPCFG_NegotiateMultilink;
  249. }
  250. //
  251. // Set up defaults
  252. //
  253. CopyMemory( &(pLcpCb->Local.Want), &LcpDefault, sizeof( LCP_OPTIONS ) );
  254. CopyMemory( &(pLcpCb->Remote.Want), &LcpDefault, sizeof( LCP_OPTIONS ) );
  255. //
  256. // Get Framing information from the driver.
  257. //
  258. dwRetCode = RasGetFramingCapabilities( pLcpCb->hPort,
  259. &RasFramingCapabilities );
  260. if ( dwRetCode != NO_ERROR )
  261. {
  262. LOCAL_FREE( *ppWorkBuf );
  263. return( dwRetCode );
  264. }
  265. pLcpCb->Local.WillNegotiate = LcpNegotiate;
  266. pLcpCb->Remote.WillNegotiate = LcpNegotiate;
  267. pLcpCb->Local.Want.MRU = RasFramingCapabilities.RFC_MaxFrameSize;
  268. pLcpCb->Remote.Want.MRU = RasFramingCapabilities.RFC_MaxFrameSize;
  269. pLcpCb->Local.Want.Negotiate = LCP_N_MAGIC;
  270. pLcpCb->Remote.Want.Negotiate = LCP_N_MAGIC;
  271. if (RasFramingCapabilities.RFC_MaxFrameSize != LCP_DEFAULT_MRU) {
  272. pLcpCb->Local.Want.Negotiate |= LCP_N_MRU;
  273. pLcpCb->Remote.Want.Negotiate |= LCP_N_MRU;
  274. }
  275. if ( RasFramingCapabilities.RFC_FramingBits & PPP_COMPRESS_ADDRESS_CONTROL )
  276. {
  277. pLcpCb->Local.Want.ACFC = TRUE;
  278. pLcpCb->Local.Want.Negotiate |= LCP_N_ACFC;
  279. pLcpCb->Remote.Want.ACFC = TRUE;
  280. pLcpCb->Remote.Want.Negotiate |= LCP_N_ACFC;
  281. }
  282. if ( RasFramingCapabilities.RFC_FramingBits & PPP_COMPRESS_PROTOCOL_FIELD )
  283. {
  284. pLcpCb->Local.Want.PFC = TRUE;
  285. pLcpCb->Local.Want.Negotiate |= LCP_N_PFC;
  286. pLcpCb->Remote.Want.PFC = TRUE;
  287. pLcpCb->Remote.Want.Negotiate |= LCP_N_PFC;
  288. }
  289. if ( RasFramingCapabilities.RFC_FramingBits & PPP_ACCM_SUPPORTED )
  290. {
  291. pLcpCb->Local.Want.ACCM = RasFramingCapabilities.RFC_DesiredACCM;
  292. pLcpCb->Local.Want.Negotiate |= LCP_N_ACCM;
  293. }
  294. if ( pLcpCb->PppConfigInfo.dwConfigMask & PPPCFG_NegotiateMultilink )
  295. {
  296. pLcpCb->Local.Want.dwEDLength =
  297. ( PppConfigInfo.EndPointDiscriminator[0] == 1 ) ? 21 : 7;
  298. CopyMemory( pLcpCb->Local.Want.EndpointDiscr,
  299. PppConfigInfo.EndPointDiscriminator,
  300. pLcpCb->Local.Want.dwEDLength );
  301. if ( ( pPppCpInit->dwDeviceType & RDT_Tunnel )
  302. && ( !pPppCpInit->fServer ) )
  303. {
  304. //
  305. // If a VPN connection goes down unexpectedly, the server doesn't
  306. // realize this for upto 2 min. When the client redials, we don't
  307. // want the server to bundle the old link and the new one. Hence,
  308. // we change the EndpointDiscriminator.
  309. //
  310. BCount++;
  311. pLcpCb->Local.Want.EndpointDiscr[pLcpCb->Local.Want.dwEDLength-1]
  312. += BCount;
  313. }
  314. pLcpCb->Local.Want.Negotiate |= LCP_N_ENDPOINT;
  315. pLcpCb->Remote.Want.Negotiate |= LCP_N_ENDPOINT;
  316. pLcpCb->Local.Want.MRRU =
  317. RasFramingCapabilities.RFC_MaxReconstructedFrameSize;
  318. pLcpCb->Remote.Want.MRRU = 1500; // Can always handle sending 1500
  319. pLcpCb->Local.Want.Negotiate |= LCP_N_MRRU;
  320. pLcpCb->Remote.Want.Negotiate |= LCP_N_MRRU;
  321. if ( RasFramingCapabilities.RFC_FramingBits &
  322. PPP_SHORT_SEQUENCE_HDR_FORMAT )
  323. {
  324. pLcpCb->Local.Want.ShortSequence = TRUE;
  325. pLcpCb->Local.Want.Negotiate |= LCP_N_SHORT_SEQ;
  326. pLcpCb->Remote.Want.ShortSequence = TRUE;
  327. pLcpCb->Remote.Want.Negotiate |= LCP_N_SHORT_SEQ;
  328. }
  329. pLcpCb->Local.WillNegotiate |= ( LCP_N_SHORT_SEQ | LCP_N_ENDPOINT |
  330. LCP_N_MRRU );
  331. pLcpCb->Remote.WillNegotiate |= ( LCP_N_SHORT_SEQ | LCP_N_ENDPOINT |
  332. LCP_N_MRRU );
  333. if ( pLcpCb->PppConfigInfo.dwConfigMask & PPPCFG_NegotiateBacp )
  334. {
  335. pLcpCb->Local.Want.dwLinkDiscriminator = WLinkDiscriminator++;
  336. pLcpCb->Remote.Want.dwLinkDiscriminator = 0;
  337. pLcpCb->Local.Want.Negotiate |= LCP_N_LINK_DISCRIM;
  338. pLcpCb->Remote.Want.Negotiate |= LCP_N_LINK_DISCRIM;
  339. pLcpCb->Local.WillNegotiate |= LCP_N_LINK_DISCRIM;
  340. pLcpCb->Remote.WillNegotiate |= LCP_N_LINK_DISCRIM;
  341. }
  342. }
  343. //
  344. // We always negotiate callback if this is not a callback
  345. //
  346. if ( !pPppCpInit->fThisIsACallback )
  347. {
  348. //
  349. // If the CBCP dll is loaded
  350. //
  351. if ( GetCpIndexFromProtocol( PPP_CBCP_PROTOCOL ) != (DWORD)-1 )
  352. {
  353. if ( pLcpCb->PppConfigInfo.dwConfigMask & PPPCFG_UseLcpExtensions )
  354. {
  355. pLcpCb->Local.Want.Negotiate |= LCP_N_CALLBACK;
  356. pLcpCb->Local.Want.Callback = PPP_NEGOTIATE_CALLBACK;
  357. }
  358. pLcpCb->Local.WillNegotiate |= LCP_N_CALLBACK;
  359. pLcpCb->Remote.WillNegotiate |= LCP_N_CALLBACK;
  360. }
  361. }
  362. //
  363. // Figure out what authentication protocols we may use for this connection.
  364. //
  365. if ( pLcpCb->PppConfigInfo.dwConfigMask & PPPCFG_NegotiatePAP )
  366. {
  367. pLcpCb->Local.fAPsAvailable |= LCP_AP_PAP;
  368. pLcpCb->Remote.fAPsAvailable |= LCP_AP_PAP;
  369. }
  370. if ( pLcpCb->PppConfigInfo.dwConfigMask & PPPCFG_NegotiateMD5CHAP )
  371. {
  372. pLcpCb->Remote.fAPsAvailable |= LCP_AP_CHAP_MD5;
  373. pLcpCb->Local.fAPsAvailable |= LCP_AP_CHAP_MD5;
  374. }
  375. if ( pLcpCb->PppConfigInfo.dwConfigMask & PPPCFG_NegotiateMSCHAP )
  376. {
  377. pLcpCb->Local.fAPsAvailable |= LCP_AP_CHAP_MS;
  378. pLcpCb->Remote.fAPsAvailable |= LCP_AP_CHAP_MS;
  379. }
  380. if ( pLcpCb->PppConfigInfo.dwConfigMask & PPPCFG_NegotiateEAP )
  381. {
  382. pLcpCb->Remote.fAPsAvailable |= LCP_AP_EAP;
  383. pLcpCb->Local.fAPsAvailable |= LCP_AP_EAP;
  384. }
  385. if ( pLcpCb->PppConfigInfo.dwConfigMask & PPPCFG_NegotiateSPAP )
  386. {
  387. pLcpCb->Local.fAPsAvailable |= LCP_AP_SPAP_NEW;
  388. pLcpCb->Remote.fAPsAvailable |= LCP_AP_SPAP_NEW;
  389. }
  390. if ( pLcpCb->PppConfigInfo.dwConfigMask & PPPCFG_NegotiateStrongMSCHAP )
  391. {
  392. pLcpCb->Local.fAPsAvailable |= LCP_AP_CHAP_MS_NEW;
  393. pLcpCb->Remote.fAPsAvailable |= LCP_AP_CHAP_MS_NEW;
  394. }
  395. if ( pLcpCb->PppConfigInfo.dwConfigMask & PPPCFG_AllowNoAuthOnDCPorts )
  396. {
  397. pLcpCb->Local.fAPsAvailable = 0;
  398. pLcpCb->Remote.fAPsAvailable = 0;
  399. }
  400. //
  401. // Make sure we have at least one authentication protocol if we are a
  402. // server or a router dialing out. Fail if we are not allow no
  403. // authentication.
  404. //
  405. if ( ( pLcpCb->Local.fAPsAvailable == 0 ) &&
  406. ( !( pLcpCb->PppConfigInfo.dwConfigMask &
  407. PPPCFG_AllowNoAuthentication ) ) &&
  408. ( ( pLcpCb->fServer ) || ( pLcpCb->fRouter ) ) )
  409. {
  410. LOCAL_FREE( *ppWorkBuf );
  411. return( ERROR_NO_AUTH_PROTOCOL_AVAILABLE );
  412. }
  413. PppLog( 2, "ConfigInfo = %x", pLcpCb->PppConfigInfo.dwConfigMask );
  414. PppLog( 2, "APs available = %x", pLcpCb->Local.fAPsAvailable );
  415. //
  416. // If this is the server side or we are a router dialing out,
  417. // we need to request an authentication protocol.
  418. //
  419. if ( ( pLcpCb->Local.fAPsAvailable > 0 ) &&
  420. (( pLcpCb->fServer ) ||
  421. ( ( pLcpCb->fRouter ) &&
  422. ( pLcpCb->PppConfigInfo.dwConfigMask & PPPCFG_AuthenticatePeer ))))
  423. {
  424. pLcpCb->Local.Want.Negotiate |= LCP_N_AUTHENT;
  425. pLcpCb->Local.WillNegotiate |= LCP_N_AUTHENT;
  426. pLcpCb->Local.Work.APDataSize = 0;
  427. pLcpCb->Local.Work.pAPData = NULL;
  428. }
  429. //
  430. // If this is the client side and no protocol other than MSCHAP v2 and EAP
  431. // is allowed, then we insist on being authenticated.
  432. //
  433. if (!( pLcpCb->fServer ))
  434. {
  435. if ( ( pLcpCb->Remote.fAPsAvailable & ~( LCP_AP_CHAP_MS_NEW |
  436. LCP_AP_EAP ) ) == 0 )
  437. {
  438. pLcpCb->Remote.Work.APDataSize = 0;
  439. pLcpCb->Remote.Work.pAPData = NULL;
  440. pLcpCb->Remote.WillNegotiate |= LCP_N_AUTHENT;
  441. pLcpCb->Remote.Want.Negotiate |= LCP_N_AUTHENT;
  442. }
  443. }
  444. //
  445. // Accept authentication if there are authentication protocols available
  446. // If it turns out that it is a client dialing in then authentication
  447. // will fail and we will renegotiate and this time we will reject
  448. // authentication option. See auth.c.
  449. //
  450. if ( pLcpCb->Remote.fAPsAvailable > 0 )
  451. {
  452. pLcpCb->Remote.Work.APDataSize = 0;
  453. pLcpCb->Remote.Work.pAPData = NULL;
  454. pLcpCb->Remote.WillNegotiate |= LCP_N_AUTHENT;
  455. }
  456. return( NO_ERROR );
  457. }
  458. //**
  459. //
  460. // Call: LcpEnd
  461. //
  462. // Returns: NO_ERROR - Success
  463. //
  464. // Description: Frees the LCP work buffer.
  465. //
  466. DWORD
  467. LcpEnd(
  468. IN VOID * pWorkBuf
  469. )
  470. {
  471. LCPCB * pLcpCb = (LCPCB *)pWorkBuf;
  472. PppLog( 2, "LcpEnd");
  473. if ( pLcpCb->Local.Work.pAPData != (PBYTE)NULL )
  474. {
  475. LOCAL_FREE( pLcpCb->Local.Work.pAPData );
  476. }
  477. if ( pLcpCb->Remote.Work.pAPData != (PBYTE)NULL )
  478. {
  479. LOCAL_FREE( pLcpCb->Remote.Work.pAPData );
  480. }
  481. if ( pWorkBuf != NULL )
  482. {
  483. LOCAL_FREE( pWorkBuf );
  484. }
  485. return( NO_ERROR );
  486. }
  487. //**
  488. //
  489. // Call: LcpReset
  490. //
  491. // Returns: NO_ERROR - Success
  492. //
  493. // Description: Called to reset the state of LCP. Will re-initialize the work
  494. // buffer.
  495. //
  496. DWORD
  497. LcpReset(
  498. IN VOID * pWorkBuf
  499. )
  500. {
  501. LCPCB * pLcpCb = (LCPCB *)pWorkBuf;
  502. PVOID pAPData;
  503. DWORD APDataSize;
  504. DWORD dwIndex;
  505. DWORD dwRetCode;
  506. //
  507. // Make sure we have at least one authentication protocol if we are a
  508. // server or a router dialing out. Fail if we are not allow no
  509. // authentication.
  510. //
  511. if ( ( pLcpCb->Local.fAPsAvailable == 0 ) &&
  512. ( !( pLcpCb->PppConfigInfo.dwConfigMask &
  513. PPPCFG_AllowNoAuthentication ) ) &&
  514. ( ( pLcpCb->fServer ) || ( pLcpCb->fRouter ) ) )
  515. {
  516. return( ERROR_NO_AUTH_PROTOCOL_AVAILABLE );
  517. }
  518. pLcpCb->dwMagicNumberFailureCount = 0;
  519. if ( pLcpCb->Local.Want.Negotiate & LCP_N_MAGIC )
  520. {
  521. srand( GetCurrentTime() );
  522. //
  523. // Shift left since rand returns a max of 0x7FFF
  524. //
  525. pLcpCb->Local.Want.MagicNumber = ( rand() << 16 );
  526. pLcpCb->Local.Want.MagicNumber += rand();
  527. //
  528. // Make sure that this is not 0
  529. //
  530. if ( pLcpCb->Local.Want.MagicNumber == 0 )
  531. {
  532. pLcpCb->Local.Want.MagicNumber = 23;
  533. }
  534. pLcpCb->Remote.Want.MagicNumber = pLcpCb->Local.Want.MagicNumber + 1;
  535. }
  536. pAPData = pLcpCb->Local.Work.pAPData;
  537. APDataSize = pLcpCb->Local.Work.APDataSize;
  538. CopyMemory( &(pLcpCb->Local.Work),
  539. &(pLcpCb->Local.Want),
  540. sizeof(LCP_OPTIONS) );
  541. pLcpCb->Local.Work.pAPData = pAPData;
  542. pLcpCb->Local.Work.APDataSize = APDataSize;
  543. pAPData = pLcpCb->Remote.Work.pAPData;
  544. APDataSize = pLcpCb->Remote.Work.APDataSize;
  545. CopyMemory( &(pLcpCb->Remote.Work),
  546. &(pLcpCb->Remote.Want),
  547. sizeof(LCP_OPTIONS));
  548. pLcpCb->Remote.Work.pAPData = pAPData;
  549. pLcpCb->Remote.Work.APDataSize = APDataSize;
  550. if ( ( pLcpCb->Local.fAPsAvailable > 0 ) &&
  551. (( pLcpCb->fServer ) ||
  552. ( ( pLcpCb->fRouter ) &&
  553. ( pLcpCb->PppConfigInfo.dwConfigMask & PPPCFG_AuthenticatePeer ))))
  554. {
  555. //
  556. // Start with the highest order bit which is the strongest protocol.
  557. //
  558. for( dwIndex = 0, pLcpCb->Local.fLastAPTried = 1;
  559. !(( pLcpCb->Local.fLastAPTried << dwIndex ) & LCP_AP_MAX );
  560. dwIndex++ )
  561. {
  562. if ( ( pLcpCb->Local.fLastAPTried << dwIndex ) &
  563. ( pLcpCb->Local.fAPsAvailable ))
  564. {
  565. pLcpCb->Local.fLastAPTried =
  566. (pLcpCb->Local.fLastAPTried << dwIndex);
  567. break;
  568. }
  569. }
  570. pLcpCb->Local.fOldLastAPTried = pLcpCb->Local.fLastAPTried;
  571. dwRetCode = MakeAuthProtocolOption( &(pLcpCb->Local) );
  572. if ( dwRetCode != NO_ERROR )
  573. {
  574. return( dwRetCode );
  575. }
  576. }
  577. //
  578. // Do the same for remote.
  579. //
  580. if ( pLcpCb->Remote.fAPsAvailable > 0 )
  581. {
  582. for( dwIndex = 0, pLcpCb->Remote.fLastAPTried = LCP_AP_FIRST;
  583. !(( pLcpCb->Remote.fLastAPTried << dwIndex ) & LCP_AP_MAX);
  584. dwIndex++ )
  585. {
  586. if ( ( pLcpCb->Remote.fLastAPTried << dwIndex ) &
  587. ( pLcpCb->Remote.fAPsAvailable ) )
  588. {
  589. pLcpCb->Remote.fLastAPTried =
  590. (pLcpCb->Remote.fLastAPTried << dwIndex);
  591. //
  592. // We need to back up one since we are the client and we haven't
  593. // sent this yet.
  594. //
  595. if ( pLcpCb->Remote.fLastAPTried == LCP_AP_FIRST )
  596. {
  597. pLcpCb->Remote.fLastAPTried = 0;
  598. }
  599. else
  600. {
  601. pLcpCb->Remote.fLastAPTried >>= 1;
  602. }
  603. pLcpCb->Remote.fOldLastAPTried = pLcpCb->Remote.fLastAPTried;
  604. break;
  605. }
  606. }
  607. }
  608. return( NO_ERROR );
  609. }
  610. //**
  611. //
  612. // Call: MakeOption
  613. //
  614. // Returns: NO_ERROR - Success
  615. // ERROR_BUFFER_TOO_SMALL - Buffer passed in is not large enough.
  616. // ERROR_INVALID_PARAMETER - Option type not recognized.
  617. //
  618. // Description: This is not an entry point, it is an internal procedure called
  619. // to build a particular option.
  620. //
  621. DWORD
  622. MakeOption(
  623. IN LCP_OPTIONS * pOptionValues,
  624. IN DWORD dwOptionType,
  625. IN PPP_OPTION * pSendOption,
  626. IN DWORD cbSendOption
  627. )
  628. {
  629. if ( cbSendOption < SizeOfOption[ dwOptionType ] )
  630. return( ERROR_BUFFER_TOO_SMALL );
  631. pSendOption->Type = (BYTE)dwOptionType;
  632. pSendOption->Length = (BYTE)(SizeOfOption[ dwOptionType ]);
  633. switch( dwOptionType )
  634. {
  635. case LCP_OPTION_MRU:
  636. HostToWireFormat16( (WORD)(pOptionValues->MRU), pSendOption->Data );
  637. break;
  638. case LCP_OPTION_ACCM:
  639. HostToWireFormat32( pOptionValues->ACCM, pSendOption->Data );
  640. break;
  641. case LCP_OPTION_AUTHENT:
  642. HostToWireFormat16( (WORD)pOptionValues->AP, pSendOption->Data );
  643. //
  644. // First check to see if we have enough space to put the
  645. // digest algorithm
  646. //
  647. if (cbSendOption<(SizeOfOption[dwOptionType]+pOptionValues->APDataSize))
  648. {
  649. return( ERROR_BUFFER_TOO_SMALL );
  650. }
  651. CopyMemory( pSendOption->Data+2,
  652. pOptionValues->pAPData,
  653. pOptionValues->APDataSize );
  654. pSendOption->Length += (BYTE)(pOptionValues->APDataSize);
  655. break;
  656. case LCP_OPTION_MAGIC:
  657. HostToWireFormat32( pOptionValues->MagicNumber,
  658. pSendOption->Data );
  659. break;
  660. case LCP_OPTION_PFC:
  661. //
  662. // This is a boolean option, there is no value.
  663. //
  664. break;
  665. case LCP_OPTION_ACFC:
  666. //
  667. // This is a boolean option, there is no value.
  668. //
  669. break;
  670. case LCP_OPTION_CALLBACK:
  671. *(pSendOption->Data) = (BYTE)(pOptionValues->Callback);
  672. break;
  673. case LCP_OPTION_MRRU:
  674. HostToWireFormat16( (WORD)(pOptionValues->MRRU), pSendOption->Data );
  675. break;
  676. case LCP_OPTION_SHORT_SEQ:
  677. //
  678. // This is a boolean option, there is no value.
  679. //
  680. break;
  681. case LCP_OPTION_ENDPOINT:
  682. //
  683. // First check to see if we have enough space to put the
  684. // discriminator
  685. //
  686. if ( cbSendOption < ( SizeOfOption[dwOptionType] +
  687. pOptionValues->dwEDLength ) )
  688. {
  689. return( ERROR_BUFFER_TOO_SMALL );
  690. }
  691. CopyMemory( pSendOption->Data,
  692. pOptionValues->EndpointDiscr,
  693. pOptionValues->dwEDLength );
  694. pSendOption->Length += (BYTE)( pOptionValues->dwEDLength );
  695. break;
  696. case LCP_OPTION_LINK_DISCRIM:
  697. HostToWireFormat16( (WORD)(pOptionValues->dwLinkDiscriminator),
  698. pSendOption->Data );
  699. break;
  700. default:
  701. //
  702. // If we do not recognize the option
  703. //
  704. return( ERROR_INVALID_PARAMETER );
  705. }
  706. return( NO_ERROR );
  707. }
  708. //**
  709. //
  710. // Call: CheckOption
  711. //
  712. // Returns: CONFIG_ACK
  713. // CONFIG_NAK
  714. // CONFIG_REJ
  715. //
  716. // Description: This is not an entry point. Called to check to see if an option
  717. // value is valid and if it is the new value is saved in the
  718. // work buffer.
  719. //
  720. DWORD
  721. CheckOption(
  722. IN LCPCB * pLcpCb,
  723. IN LCP_SIDE * pLcpSide,
  724. IN PPP_OPTION * pOption,
  725. IN BOOL fMakingResult
  726. )
  727. {
  728. DWORD dwIndex;
  729. DWORD dwAPDataSize;
  730. DWORD dwRetCode = CONFIG_ACK;
  731. if ( pOption->Length < SizeOfOption[ pOption->Type ] )
  732. return( CONFIG_REJ );
  733. //
  734. // If we do not want to negotiate the option we CONFIG_REJ it.
  735. //
  736. if ( !( pLcpSide->WillNegotiate & (1 << pOption->Type)) )
  737. return( CONFIG_REJ );
  738. switch( pOption->Type )
  739. {
  740. case LCP_OPTION_MRU:
  741. pLcpSide->Work.MRU = WireToHostFormat16( pOption->Data );
  742. //
  743. // Check to see if this value is appropriate
  744. //
  745. if ( !fMakingResult )
  746. {
  747. //
  748. // We cannot receive bigger packets.
  749. //
  750. if ( pLcpSide->Work.MRU > pLcpSide->Want.MRU )
  751. {
  752. //
  753. // Check to see if the server nak'd. If so
  754. // check to see if peer wants <= 1500 mru
  755. // and if we have already sent the request
  756. // 2 times, just ack peers mru.
  757. //
  758. if(pLcpSide->Work.MRU <= LCP_DEFAULT_MRU)
  759. {
  760. if(pLcpCb->dwMRUFailureCount > 0)
  761. {
  762. pLcpCb->dwMRUFailureCount--;
  763. }
  764. if(pLcpCb->dwMRUFailureCount == 0)
  765. {
  766. break;
  767. }
  768. }
  769. pLcpSide->Work.MRU = pLcpSide->Want.MRU;
  770. dwRetCode = CONFIG_NAK;
  771. }
  772. }
  773. break;
  774. case LCP_OPTION_ACCM:
  775. pLcpSide->Work.ACCM = WireToHostFormat32( pOption->Data );
  776. //
  777. // If we are responding to a request, we accept it blindly, if we are
  778. // processing a NAK, then the remote host may ask to escape more
  779. // control characters than we require, but must escape at least the
  780. // control chars that we require.
  781. //
  782. if ( !fMakingResult )
  783. {
  784. if ( pLcpSide->Work.ACCM !=
  785. ( pLcpSide->Work.ACCM | pLcpSide->Want.ACCM ) )
  786. {
  787. pLcpSide->Work.ACCM |= pLcpSide->Want.ACCM;
  788. dwRetCode = CONFIG_NAK;
  789. }
  790. }
  791. break;
  792. case LCP_OPTION_AUTHENT:
  793. pLcpSide->Work.AP = WireToHostFormat16( pOption->Data );
  794. //
  795. // If there was Authentication data.
  796. //
  797. if ( pOption->Length > PPP_OPTION_HDR_LEN + 2 )
  798. {
  799. dwAPDataSize = pOption->Length - PPP_OPTION_HDR_LEN - 2;
  800. if ( dwAPDataSize != pLcpSide->Work.APDataSize )
  801. {
  802. pLcpSide->Work.APDataSize = dwAPDataSize;
  803. if ( NULL != pLcpSide->Work.pAPData )
  804. {
  805. LOCAL_FREE( pLcpSide->Work.pAPData );
  806. pLcpSide->Work.pAPData = NULL;
  807. }
  808. pLcpSide->Work.pAPData = (PBYTE)LOCAL_ALLOC(
  809. LPTR,
  810. pLcpSide->Work.APDataSize );
  811. if ( NULL == pLcpSide->Work.pAPData )
  812. {
  813. pLcpSide->Work.APDataSize = 0;
  814. return( CONFIG_REJ );
  815. }
  816. }
  817. CopyMemory( pLcpSide->Work.pAPData,
  818. pOption->Data+2,
  819. pLcpSide->Work.APDataSize );
  820. }
  821. else
  822. {
  823. pLcpSide->Work.APDataSize = 0;
  824. }
  825. pLcpSide->fOldLastAPTried = pLcpSide->fLastAPTried;
  826. switch( pLcpSide->Work.AP )
  827. {
  828. case PPP_CHAP_PROTOCOL:
  829. //
  830. // If CHAP is not available
  831. //
  832. if ( !( pLcpSide->fAPsAvailable & ( LCP_AP_CHAP_MS |
  833. LCP_AP_CHAP_MD5 |
  834. LCP_AP_CHAP_MS_NEW )))
  835. {
  836. dwRetCode = CONFIG_NAK;
  837. break;
  838. }
  839. //
  840. // If there was no digest algorithm then we respond with the
  841. // digest algorithm the next time. To do this we need to back up
  842. // one in the list of APs tried so that we try this AP again.
  843. //
  844. if ( pOption->Length < (PPP_OPTION_HDR_LEN + 3) )
  845. {
  846. pLcpSide->fLastAPTried = 0;
  847. dwRetCode = CONFIG_NAK;
  848. break;
  849. }
  850. if ( *(pLcpSide->Work.pAPData) == PPP_CHAP_DIGEST_MSEXT )
  851. {
  852. if ( !( pLcpSide->fAPsAvailable & LCP_AP_CHAP_MS ) )
  853. {
  854. dwRetCode = CONFIG_NAK;
  855. }
  856. }
  857. else if ( *(pLcpSide->Work.pAPData) == PPP_CHAP_DIGEST_MSEXT_NEW )
  858. {
  859. if ( !( pLcpSide->fAPsAvailable & LCP_AP_CHAP_MS_NEW ) )
  860. {
  861. dwRetCode = CONFIG_NAK;
  862. }
  863. }
  864. else if ( *(pLcpSide->Work.pAPData) == PPP_CHAP_DIGEST_MD5 )
  865. {
  866. if ( !( pLcpSide->fAPsAvailable & LCP_AP_CHAP_MD5 ) )
  867. {
  868. dwRetCode = CONFIG_NAK;
  869. }
  870. }
  871. else
  872. {
  873. dwRetCode = CONFIG_NAK;
  874. }
  875. break;
  876. case PPP_PAP_PROTOCOL:
  877. if ( !( pLcpSide->fAPsAvailable & LCP_AP_PAP ) )
  878. {
  879. dwRetCode = CONFIG_NAK;
  880. }
  881. break;
  882. case PPP_EAP_PROTOCOL:
  883. if ( !( pLcpSide->fAPsAvailable & LCP_AP_EAP ) )
  884. {
  885. dwRetCode = CONFIG_NAK;
  886. }
  887. break;
  888. case PPP_SPAP_NEW_PROTOCOL:
  889. if ( !( pLcpSide->fAPsAvailable & LCP_AP_SPAP_NEW ) )
  890. {
  891. dwRetCode = CONFIG_NAK;
  892. break;
  893. }
  894. if ( pOption->Length < (PPP_OPTION_HDR_LEN+6) )
  895. {
  896. dwRetCode = CONFIG_NAK;
  897. //
  898. // We are a client responding to a remote CONFIG_REQ
  899. //
  900. if ( fMakingResult )
  901. {
  902. pLcpSide->fLastAPTried = ( LCP_AP_SPAP_NEW >> 1 );
  903. }
  904. break;
  905. }
  906. //
  907. // If encryption algorithm is not 1. NAK with 1.
  908. //
  909. if (WireToHostFormat32(pLcpSide->Work.pAPData) != LCP_SPAP_VERSION)
  910. {
  911. //
  912. // We are a client responding to a remote CONFIG_REQ
  913. //
  914. if ( fMakingResult )
  915. {
  916. pLcpSide->fLastAPTried = ( LCP_AP_SPAP_NEW >> 1 );
  917. }
  918. dwRetCode = CONFIG_NAK;
  919. break;
  920. }
  921. break;
  922. default:
  923. dwRetCode = CONFIG_NAK;
  924. break;
  925. }
  926. if ( dwRetCode == CONFIG_NAK )
  927. {
  928. //
  929. // The fLastAPTried is set to 0, then we set to LCP_AP_FIRST
  930. //
  931. if ( pLcpSide->fLastAPTried == 0 )
  932. {
  933. pLcpSide->fLastAPTried = LCP_AP_FIRST;
  934. }
  935. //
  936. // We look for the next weakest protocol available.
  937. //
  938. for( dwIndex = 1;
  939. !(( pLcpSide->fLastAPTried << dwIndex ) & LCP_AP_MAX);
  940. dwIndex++ )
  941. {
  942. if ( ( pLcpSide->fLastAPTried << dwIndex ) & pLcpSide->fAPsAvailable )
  943. {
  944. pLcpSide->fLastAPTried = (pLcpSide->fLastAPTried<<dwIndex);
  945. break;
  946. }
  947. }
  948. MakeAuthProtocolOption( pLcpSide );
  949. }
  950. break;
  951. case LCP_OPTION_MAGIC:
  952. pLcpSide->Work.MagicNumber = WireToHostFormat32( pOption->Data );
  953. if ( fMakingResult )
  954. {
  955. //
  956. // Ensure that magic numbers are different and that the remote
  957. // request does not contain a magic number of 0.
  958. //
  959. if ( (pLcpSide->Work.MagicNumber == pLcpCb->Local.Work.MagicNumber)
  960. || ( pLcpSide->Work.MagicNumber == 0 ) )
  961. {
  962. if (pLcpSide->Work.MagicNumber==pLcpCb->Local.Work.MagicNumber)
  963. {
  964. ++(pLcpCb->dwMagicNumberFailureCount);
  965. }
  966. //
  967. // Shift left since rand returns a max of 0x7FFF
  968. //
  969. pLcpSide->Work.MagicNumber = ( rand() << 16 );
  970. pLcpSide->Work.MagicNumber += rand();
  971. if ( pLcpSide->Work.MagicNumber == 0 )
  972. {
  973. pLcpSide->Work.MagicNumber = 48;
  974. }
  975. dwRetCode = CONFIG_NAK;
  976. }
  977. }
  978. else
  979. {
  980. //
  981. // The remote peer NAK'ed with a magic number, check to see if
  982. // the magic number in the NAK is the same as what we NAK'ed last
  983. //
  984. if ( pLcpSide->Work.MagicNumber == pLcpCb->Remote.Work.MagicNumber )
  985. {
  986. ++(pLcpCb->dwMagicNumberFailureCount);
  987. //
  988. // Shift left since rand returns a max of 0x7FFF
  989. //
  990. pLcpSide->Work.MagicNumber = ( rand() << 16 );
  991. pLcpSide->Work.MagicNumber += rand();
  992. if ( pLcpSide->Work.MagicNumber == 0 )
  993. {
  994. pLcpSide->Work.MagicNumber = 93;
  995. }
  996. dwRetCode = CONFIG_NAK;
  997. }
  998. }
  999. break;
  1000. case LCP_OPTION_PFC:
  1001. pLcpSide->Work.PFC = TRUE;
  1002. if ( pLcpSide->Want.PFC == FALSE )
  1003. dwRetCode = CONFIG_REJ;
  1004. break;
  1005. case LCP_OPTION_ACFC:
  1006. pLcpSide->Work.ACFC = TRUE;
  1007. if ( pLcpSide->Want.ACFC == FALSE )
  1008. dwRetCode = CONFIG_REJ;
  1009. break;
  1010. case LCP_OPTION_CALLBACK:
  1011. pLcpSide->Work.Callback = *(pOption->Data);
  1012. //
  1013. // If the Callback control protocol is not loaded.
  1014. //
  1015. if ( GetCpIndexFromProtocol(PPP_CBCP_PROTOCOL) == (DWORD)-1 )
  1016. {
  1017. dwRetCode = CONFIG_REJ;
  1018. }
  1019. else if ( pLcpSide->Work.Callback != PPP_NEGOTIATE_CALLBACK )
  1020. {
  1021. if ( fMakingResult )
  1022. {
  1023. //
  1024. // We only understand this option.
  1025. //
  1026. pLcpSide->Work.Callback = PPP_NEGOTIATE_CALLBACK;
  1027. dwRetCode = CONFIG_NAK;
  1028. }
  1029. else
  1030. {
  1031. //
  1032. // If we are processing a NAK from the remote peer, then we
  1033. // simply do not negotiate this option again.
  1034. //
  1035. dwRetCode = CONFIG_REJ;
  1036. }
  1037. }
  1038. break;
  1039. case LCP_OPTION_MRRU:
  1040. pLcpSide->Work.MRRU = WireToHostFormat16( pOption->Data );
  1041. //
  1042. // Check to see if this value is appropriate
  1043. //
  1044. if ( fMakingResult )
  1045. {
  1046. //
  1047. // We cannot send smaller reconstructed packets.
  1048. //
  1049. if ( pLcpSide->Work.MRRU < pLcpSide->Want.MRRU )
  1050. {
  1051. pLcpSide->Work.MRRU = pLcpSide->Want.MRRU;
  1052. dwRetCode = CONFIG_NAK;
  1053. }
  1054. }
  1055. else
  1056. {
  1057. //
  1058. // We cannot receive bigger reconstructed packets.
  1059. //
  1060. if ( pLcpSide->Work.MRRU > pLcpSide->Want.MRRU )
  1061. {
  1062. pLcpSide->Work.MRRU = pLcpSide->Want.MRRU;
  1063. dwRetCode = CONFIG_NAK;
  1064. }
  1065. }
  1066. break;
  1067. case LCP_OPTION_SHORT_SEQ:
  1068. pLcpSide->Work.ShortSequence = TRUE;
  1069. if ( pLcpSide->Want.ShortSequence == FALSE )
  1070. dwRetCode = CONFIG_REJ;
  1071. break;
  1072. case LCP_OPTION_ENDPOINT:
  1073. //
  1074. // If this option was NAKed then we do not change this value and
  1075. // simply resend the config request
  1076. //
  1077. if ( !fMakingResult )
  1078. {
  1079. break;
  1080. }
  1081. ZeroMemory( pLcpSide->Work.EndpointDiscr,
  1082. sizeof( pLcpSide->Work.EndpointDiscr ) );
  1083. //
  1084. // Make sure that the discriminator can fit into our storage allocated
  1085. // for it, otherwise simply truncate and hope that it is unique. We do
  1086. // not want to reject it since we want bundling to work.
  1087. //
  1088. if ( ( pOption->Length - PPP_OPTION_HDR_LEN ) >
  1089. sizeof(pLcpSide->Work.EndpointDiscr) )
  1090. {
  1091. pLcpSide->Work.dwEDLength = sizeof( pLcpSide->Work.EndpointDiscr );
  1092. }
  1093. else
  1094. {
  1095. pLcpSide->Work.dwEDLength = pOption->Length - PPP_OPTION_HDR_LEN;
  1096. }
  1097. CopyMemory( pLcpSide->Work.EndpointDiscr,
  1098. pOption->Data,
  1099. pLcpSide->Work.dwEDLength );
  1100. break;
  1101. case LCP_OPTION_LINK_DISCRIM:
  1102. pLcpSide->Work.dwLinkDiscriminator = WireToHostFormat16( pOption->Data );
  1103. break;
  1104. default:
  1105. //
  1106. // If we do not recognize the option we CONFIG_REJ it.
  1107. //
  1108. dwRetCode = CONFIG_REJ;
  1109. break;
  1110. }
  1111. return( dwRetCode );
  1112. }
  1113. //**
  1114. //
  1115. // Call: BuildOptionList
  1116. //
  1117. // Returns: NO_ERROR - Success
  1118. // Non-zero returns from MakeOption
  1119. //
  1120. // Description: This is not an entry point. Will build a list of options
  1121. // either for a configure request or a configure result.
  1122. //
  1123. DWORD
  1124. BuildOptionList(
  1125. IN OUT BYTE * pOptions,
  1126. IN OUT DWORD * pcbOptions,
  1127. IN LCP_OPTIONS * LcpOptions,
  1128. IN DWORD Negotiate
  1129. )
  1130. {
  1131. DWORD OptionType;
  1132. DWORD dwRetCode;
  1133. DWORD cbOptionLength = *pcbOptions;
  1134. for ( OptionType = 1;
  1135. OptionType <= LCP_OPTION_LIMIT;
  1136. OptionType++ )
  1137. {
  1138. if ( Negotiate & ( 1 << OptionType ))
  1139. {
  1140. if ( ( dwRetCode = MakeOption( LcpOptions,
  1141. OptionType,
  1142. (PPP_OPTION *)pOptions,
  1143. cbOptionLength ) ) != NO_ERROR )
  1144. return( dwRetCode );
  1145. cbOptionLength -= ((PPP_OPTION*)pOptions)->Length;
  1146. pOptions += ((PPP_OPTION*)pOptions)->Length;
  1147. }
  1148. }
  1149. *pcbOptions -= cbOptionLength;
  1150. return( NO_ERROR );
  1151. }
  1152. //**
  1153. //
  1154. // Call: LcpMakeConfigRequest
  1155. //
  1156. // Returns: NO_ERROR - Success
  1157. // Non-zero returns from BuildOptionList
  1158. //
  1159. // Description: This is a entry point that is called to make a configure
  1160. // request packet.
  1161. //
  1162. DWORD
  1163. LcpMakeConfigRequest(
  1164. IN VOID * pWorkBuffer,
  1165. IN PPP_CONFIG * pSendConfig,
  1166. IN DWORD cbSendConfig
  1167. )
  1168. {
  1169. LCPCB * pLcpCb = (LCPCB*)pWorkBuffer;
  1170. DWORD dwRetCode;
  1171. cbSendConfig -= PPP_CONFIG_HDR_LEN;
  1172. dwRetCode = BuildOptionList( pSendConfig->Data,
  1173. &cbSendConfig,
  1174. &(pLcpCb->Local.Work),
  1175. pLcpCb->Local.Work.Negotiate );
  1176. if ( dwRetCode != NO_ERROR )
  1177. return( dwRetCode );
  1178. pSendConfig->Code = CONFIG_REQ;
  1179. HostToWireFormat16( (WORD)(cbSendConfig + PPP_CONFIG_HDR_LEN),
  1180. pSendConfig->Length );
  1181. return( NO_ERROR );
  1182. }
  1183. //**
  1184. //
  1185. // Call: LcpMakeConfigResult
  1186. //
  1187. // Returns:
  1188. //
  1189. // Description:
  1190. //
  1191. DWORD
  1192. LcpMakeConfigResult(
  1193. IN VOID * pWorkBuffer,
  1194. IN PPP_CONFIG * pRecvConfig,
  1195. OUT PPP_CONFIG * pSendConfig,
  1196. IN DWORD cbSendConfig,
  1197. IN BOOL fRejectNaks
  1198. )
  1199. {
  1200. DWORD dwDesired;
  1201. DWORD dwRetCode;
  1202. LCPCB * pLcpCb = (LCPCB*)pWorkBuffer;
  1203. DWORD ResultType = CONFIG_ACK;
  1204. PPP_OPTION * pRecvOption = (PPP_OPTION *)(pRecvConfig->Data);
  1205. PPP_OPTION * pSendOption = (PPP_OPTION *)(pSendConfig->Data);
  1206. LONG lSendLength = cbSendConfig - PPP_CONFIG_HDR_LEN;
  1207. LONG lRecvLength = WireToHostFormat16( pRecvConfig->Length )
  1208. - PPP_CONFIG_HDR_LEN;
  1209. //
  1210. // Clear negotiate mask
  1211. //
  1212. pLcpCb->Remote.Work.Negotiate = 0;
  1213. //
  1214. // Process options requested by remote host
  1215. //
  1216. while( lRecvLength > 0 )
  1217. {
  1218. if ( pRecvOption->Length == 0 )
  1219. return( ERROR_PPP_INVALID_PACKET );
  1220. if ( ( lRecvLength -= pRecvOption->Length ) < 0 )
  1221. return( ERROR_PPP_INVALID_PACKET );
  1222. dwRetCode = CheckOption( pLcpCb, &(pLcpCb->Remote), pRecvOption, TRUE );
  1223. //
  1224. // If we were building an ACK and we got a NAK or reject OR
  1225. // we were building a NAK and we got a reject.
  1226. //
  1227. if ( (( ResultType == CONFIG_ACK ) && ( dwRetCode != CONFIG_ACK )) ||
  1228. (( ResultType == CONFIG_NAK ) && ( dwRetCode == CONFIG_REJ )) )
  1229. {
  1230. ResultType = dwRetCode;
  1231. pSendOption = (PPP_OPTION *)(pSendConfig->Data);
  1232. lSendLength = cbSendConfig - PPP_CONFIG_HDR_LEN;
  1233. }
  1234. //
  1235. // Remember that we processed this option
  1236. //
  1237. if ( ( dwRetCode != CONFIG_REJ ) &&
  1238. ( pRecvOption->Type <= LCP_OPTION_LIMIT ) )
  1239. {
  1240. pLcpCb->Remote.Work.Negotiate |= ( 1 << pRecvOption->Type );
  1241. }
  1242. //
  1243. // Add the option to the list.
  1244. //
  1245. if ( dwRetCode == ResultType )
  1246. {
  1247. //
  1248. // If this option is to be rejected, simply copy the
  1249. // rejected option to the send buffer
  1250. //
  1251. if ( ( dwRetCode == CONFIG_REJ ) ||
  1252. ( ( dwRetCode == CONFIG_NAK ) && ( fRejectNaks ) ) )
  1253. {
  1254. CopyMemory( pSendOption, pRecvOption, pRecvOption->Length );
  1255. }
  1256. else
  1257. {
  1258. if ( ( dwRetCode = MakeOption( &(pLcpCb->Remote.Work),
  1259. pRecvOption->Type,
  1260. pSendOption,
  1261. lSendLength ) ) != NO_ERROR )
  1262. return( dwRetCode );
  1263. }
  1264. lSendLength -= pSendOption->Length;
  1265. pSendOption = (PPP_OPTION *)
  1266. ( (BYTE *)pSendOption + pSendOption->Length );
  1267. }
  1268. pRecvOption = (PPP_OPTION *)((BYTE*)pRecvOption + pRecvOption->Length);
  1269. }
  1270. //
  1271. // If this was an NAK and we have cannot send any more NAKS then we
  1272. // make this a REJECT packet
  1273. //
  1274. if ( ( ResultType == CONFIG_NAK ) && fRejectNaks )
  1275. pSendConfig->Code = CONFIG_REJ;
  1276. else
  1277. pSendConfig->Code = (BYTE)ResultType;
  1278. HostToWireFormat16( (WORD)(cbSendConfig - lSendLength),
  1279. pSendConfig->Length );
  1280. //
  1281. // If we want to be authenticated, but the other side doesn't try to
  1282. // authenticate us, NAK with LCP_N_AUTHENT.
  1283. //
  1284. if ( ( pLcpCb->Remote.Want.Negotiate & LCP_N_AUTHENT ) &
  1285. ~( pLcpCb->Remote.Work.Negotiate ) )
  1286. {
  1287. DWORD cbOptions;
  1288. //
  1289. // We cannot send a NAK if we are sending a REJECT
  1290. //
  1291. if ( ResultType != CONFIG_REJ )
  1292. {
  1293. if ( pLcpCb->Remote.fAPsAvailable & LCP_AP_EAP )
  1294. {
  1295. pLcpCb->Remote.fLastAPTried = LCP_AP_EAP;
  1296. }
  1297. else
  1298. {
  1299. pLcpCb->Remote.fLastAPTried = LCP_AP_CHAP_MS_NEW;
  1300. }
  1301. MakeAuthProtocolOption( &(pLcpCb->Remote) );
  1302. if ( ResultType == CONFIG_ACK )
  1303. {
  1304. ResultType = CONFIG_NAK;
  1305. pSendOption = (PPP_OPTION *)(pSendConfig->Data);
  1306. lSendLength = cbSendConfig - PPP_CONFIG_HDR_LEN;
  1307. }
  1308. cbOptions = lSendLength;
  1309. dwRetCode = BuildOptionList(
  1310. (BYTE*)pSendOption,
  1311. &cbOptions,
  1312. &(pLcpCb->Remote.Work),
  1313. LCP_N_AUTHENT );
  1314. if ( dwRetCode != NO_ERROR )
  1315. {
  1316. return( dwRetCode );
  1317. }
  1318. pSendConfig->Code = CONFIG_NAK;
  1319. HostToWireFormat16( (WORD)(cbSendConfig - lSendLength + cbOptions),
  1320. pSendConfig->Length );
  1321. }
  1322. }
  1323. //
  1324. // If we are rejecting this packet then we restore the LastAPTried value
  1325. //
  1326. if ( pSendConfig->Code == CONFIG_REJ )
  1327. {
  1328. pLcpCb->Remote.fLastAPTried = pLcpCb->Remote.fOldLastAPTried;
  1329. }
  1330. else
  1331. {
  1332. pLcpCb->Remote.fOldLastAPTried = pLcpCb->Remote.fLastAPTried;
  1333. }
  1334. //
  1335. // If we have more than 3 conflicts with the magic number then we assume
  1336. // that we are talking with ourself.
  1337. //
  1338. if ((ResultType == CONFIG_NAK) && (pLcpCb->dwMagicNumberFailureCount > 3))
  1339. {
  1340. return( ERROR_PPP_LOOPBACK_DETECTED );
  1341. }
  1342. return( NO_ERROR );
  1343. }
  1344. //**
  1345. //
  1346. // Call: LcpConfigAckReceived
  1347. //
  1348. // Returns:
  1349. //
  1350. // Description:
  1351. //
  1352. DWORD
  1353. LcpConfigAckReceived(
  1354. IN VOID * pWorkBuffer,
  1355. IN PPP_CONFIG * pRecvConfig
  1356. )
  1357. {
  1358. DWORD dwRetCode;
  1359. BYTE ConfigReqSent[LCP_DEFAULT_MRU];
  1360. LCPCB * pLcpCb = (LCPCB *)pWorkBuffer;
  1361. PPP_OPTION * pRecvOption = (PPP_OPTION *)(pRecvConfig->Data);
  1362. DWORD cbConfigReqSent = sizeof( ConfigReqSent );
  1363. DWORD dwLength = WireToHostFormat16( pRecvConfig->Length )
  1364. - PPP_CONFIG_HDR_LEN;
  1365. //
  1366. // Get a copy of last request we sent
  1367. //
  1368. dwRetCode = BuildOptionList( ConfigReqSent,
  1369. &cbConfigReqSent,
  1370. &(pLcpCb->Local.Work),
  1371. pLcpCb->Local.Work.Negotiate );
  1372. if ( dwRetCode != NO_ERROR )
  1373. return( dwRetCode );
  1374. //
  1375. // Overall buffer length should match
  1376. //
  1377. if ( dwLength != cbConfigReqSent )
  1378. {
  1379. //
  1380. // Hack to work around WinCE bug on the server side only.
  1381. // If we request EAP, WinCE ACKs without auth option.
  1382. // Bug#333332
  1383. //
  1384. LCP_OPTIONS * pOptionValues = &(pLcpCb->Local.Work);
  1385. //
  1386. // If we are a client then we simply return
  1387. //
  1388. if ( !pLcpCb->fServer )
  1389. return( ERROR_PPP_INVALID_PACKET );
  1390. //
  1391. // If we requested EAP
  1392. //
  1393. if ( pOptionValues->AP == PPP_EAP_PROTOCOL )
  1394. {
  1395. DWORD dwIndex;
  1396. //
  1397. // Check to see if ACK did not contain the auth option
  1398. //
  1399. while ( dwLength > 0 )
  1400. {
  1401. if ( pRecvOption->Length == 0 )
  1402. return( ERROR_PPP_INVALID_PACKET );
  1403. if ( (long)(dwLength -= pRecvOption->Length) < 0 )
  1404. return( ERROR_PPP_INVALID_PACKET );
  1405. if ( pRecvOption->Length < SizeOfOption[ pRecvOption->Type ] )
  1406. return( ERROR_PPP_INVALID_PACKET );
  1407. if ( pRecvOption->Type == LCP_OPTION_AUTHENT )
  1408. return( ERROR_PPP_INVALID_PACKET );
  1409. pRecvOption = (PPP_OPTION *)((BYTE*)pRecvOption + pRecvOption->Length);
  1410. }
  1411. //
  1412. // If we get here then no authentication option was sent in the ACK
  1413. // so we need to treat this as a NAK. Go to the next auth protocol.
  1414. //
  1415. pLcpCb->Local.fLastAPTried = LCP_AP_EAP;
  1416. //
  1417. // We look for the next weakest protocol available.
  1418. //
  1419. for( dwIndex = 1;
  1420. !(( pLcpCb->Local.fLastAPTried << dwIndex ) & LCP_AP_MAX);
  1421. dwIndex++ )
  1422. {
  1423. if ( ( pLcpCb->Local.fLastAPTried << dwIndex ) &
  1424. pLcpCb->Local.fAPsAvailable )
  1425. {
  1426. pLcpCb->Local.fLastAPTried = (pLcpCb->Local.fLastAPTried << dwIndex );
  1427. break;
  1428. }
  1429. }
  1430. MakeAuthProtocolOption( &(pLcpCb->Local) );
  1431. }
  1432. return( ERROR_PPP_INVALID_PACKET );
  1433. }
  1434. //
  1435. // Each byte should match
  1436. //
  1437. if ( memcmp( ConfigReqSent, pRecvConfig->Data, dwLength ) != 0 )
  1438. return( ERROR_PPP_INVALID_PACKET );
  1439. return( NO_ERROR );
  1440. }
  1441. //**
  1442. //
  1443. // Call: LcpConfigNakReceived
  1444. //
  1445. // Returns:
  1446. //
  1447. // Description:
  1448. //
  1449. DWORD
  1450. LcpConfigNakReceived(
  1451. IN VOID * pWorkBuffer,
  1452. IN PPP_CONFIG * pRecvConfig
  1453. )
  1454. {
  1455. DWORD dwResult;
  1456. LCPCB * pLcpCb = (LCPCB *)pWorkBuffer;
  1457. PPP_OPTION * pOption = (PPP_OPTION*)(pRecvConfig->Data);
  1458. DWORD dwLastOption = 0;
  1459. LONG lcbRecvConfig = WireToHostFormat16( pRecvConfig->Length )
  1460. - PPP_CONFIG_HDR_LEN;
  1461. //
  1462. // First, process in order. Then, process extra "important" options
  1463. //
  1464. while ( lcbRecvConfig > 0 )
  1465. {
  1466. if ( pOption->Length == 0 )
  1467. return( ERROR_PPP_INVALID_PACKET );
  1468. if ( ( lcbRecvConfig -= pOption->Length ) < 0 )
  1469. return( ERROR_PPP_INVALID_PACKET );
  1470. //
  1471. // If this option was not requested, we mark it as negotiable
  1472. //
  1473. if ( ( pOption->Type <= LCP_OPTION_LIMIT ) &&
  1474. ( pLcpCb->Local.WillNegotiate & (1 << pOption->Type) ) &&
  1475. !( pLcpCb->Local.Work.Negotiate & (1 << pOption->Type) ) )
  1476. {
  1477. pLcpCb->Local.Work.Negotiate |= (1 << pOption->Type );
  1478. }
  1479. dwLastOption = pOption->Type;
  1480. dwResult = CheckOption( pLcpCb, &(pLcpCb->Local), pOption, FALSE );
  1481. //
  1482. // Update the negotiation status. If we cannot accept this option,
  1483. // then we will not send it again.
  1484. //
  1485. if (( dwResult == CONFIG_REJ ) && ( pOption->Type <= LCP_OPTION_LIMIT ))
  1486. pLcpCb->Local.Work.Negotiate &= ~(1 << pOption->Type);
  1487. pOption = (PPP_OPTION *)( (BYTE *)pOption + pOption->Length );
  1488. }
  1489. return( NO_ERROR );
  1490. }
  1491. //**
  1492. //
  1493. // Call: LcpConfigRejReceived
  1494. //
  1495. // Returns:
  1496. //
  1497. // Description:
  1498. //
  1499. DWORD
  1500. LcpConfigRejReceived(
  1501. IN VOID * pWorkBuffer,
  1502. IN PPP_CONFIG * pRecvConfig
  1503. )
  1504. {
  1505. DWORD dwRetCode;
  1506. LCPCB * pLcpCb = (LCPCB *)pWorkBuffer;
  1507. PPP_OPTION * pOption = (PPP_OPTION*)(pRecvConfig->Data);
  1508. DWORD dwLastOption = 0;
  1509. BYTE ReqOption[LCP_DEFAULT_MRU];
  1510. LONG lcbRecvConfig = WireToHostFormat16( pRecvConfig->Length )
  1511. - PPP_CONFIG_HDR_LEN;
  1512. //
  1513. // Process in order, checking for errors
  1514. //
  1515. while ( lcbRecvConfig > 0 )
  1516. {
  1517. if ( pOption->Length == 0 )
  1518. return( ERROR_PPP_INVALID_PACKET );
  1519. if ( ( lcbRecvConfig -= pOption->Length ) < 0 )
  1520. return( ERROR_PPP_INVALID_PACKET );
  1521. //
  1522. // Cannot receive an option out of order or an option that was
  1523. // not requested.
  1524. //
  1525. if ( ( pOption->Type <= LCP_OPTION_LIMIT ) &&
  1526. (( pOption->Type < dwLastOption ) ||
  1527. ( !( pLcpCb->Local.Work.Negotiate & (1 << pOption->Type)))) )
  1528. return( ERROR_PPP_INVALID_PACKET );
  1529. //
  1530. // If we are a server and the client rejects the authentication
  1531. // protocol then we fail to converge, if we are not set to allow no
  1532. // authentication.
  1533. //
  1534. if ( ( pLcpCb->Local.Want.Negotiate & LCP_N_AUTHENT ) &&
  1535. ( pOption->Type == LCP_OPTION_AUTHENT ) &&
  1536. ( !( pLcpCb->PppConfigInfo.dwConfigMask &
  1537. PPPCFG_AllowNoAuthentication ) ) )
  1538. {
  1539. return( ERROR_PEER_REFUSED_AUTH );
  1540. }
  1541. //
  1542. // The option should not have been modified in any way
  1543. //
  1544. if ( ( dwRetCode = MakeOption( &(pLcpCb->Local.Work),
  1545. pOption->Type,
  1546. (PPP_OPTION *)ReqOption,
  1547. sizeof( ReqOption ) ) ) != NO_ERROR )
  1548. return( dwRetCode );
  1549. if ( memcmp( ReqOption, pOption, pOption->Length ) != 0 )
  1550. return( ERROR_PPP_INVALID_PACKET );
  1551. dwLastOption = pOption->Type;
  1552. //
  1553. // The next configure request should not contain this option
  1554. //
  1555. if ( pOption->Type <= LCP_OPTION_LIMIT )
  1556. pLcpCb->Local.Work.Negotiate &= ~(1 << pOption->Type);
  1557. pOption = (PPP_OPTION *)( (BYTE *)pOption + pOption->Length );
  1558. }
  1559. return( NO_ERROR );
  1560. }
  1561. //**
  1562. //
  1563. // Call: LcpThisLayerStarted
  1564. //
  1565. // Returns:
  1566. //
  1567. // Description:
  1568. //
  1569. DWORD
  1570. LcpThisLayerStarted(
  1571. IN VOID * pWorkBuffer
  1572. )
  1573. {
  1574. return( NO_ERROR );
  1575. }
  1576. //**
  1577. //
  1578. // Call: LcpThisLayerFinished
  1579. //
  1580. // Returns:
  1581. //
  1582. // Description:
  1583. //
  1584. DWORD
  1585. LcpThisLayerFinished(
  1586. IN VOID * pWorkBuffer
  1587. )
  1588. {
  1589. return( NO_ERROR );
  1590. }
  1591. //**
  1592. //
  1593. // Call: LcpThisLayerUp
  1594. //
  1595. // Returns: None
  1596. //
  1597. // Description: Sets the framing parameters to what was negotiated.
  1598. //
  1599. DWORD
  1600. LcpThisLayerUp(
  1601. IN VOID * pWorkBuffer
  1602. )
  1603. {
  1604. DWORD dwRetCode = NO_ERROR;
  1605. RAS_FRAMING_INFO RasFramingInfo;
  1606. DWORD LocalMagicNumber;
  1607. DWORD RemoteMagicNumber;
  1608. DWORD LocalAuthProtocol;
  1609. DWORD RemoteAuthProtocol;
  1610. LCPCB * pLcpCb = (LCPCB *)pWorkBuffer;
  1611. PCB * pPcb;
  1612. pPcb = GetPCBPointerFromhPort( pLcpCb->hPort );
  1613. if ( pPcb == (PCB *)NULL )
  1614. {
  1615. return( NO_ERROR );
  1616. }
  1617. ZeroMemory( &RasFramingInfo, sizeof( RasFramingInfo ) );
  1618. if ( pLcpCb->Local.Work.Negotiate & LCP_N_MRU )
  1619. {
  1620. RasFramingInfo.RFI_MaxRecvFrameSize = pLcpCb->Local.Work.MRU;
  1621. }
  1622. else
  1623. {
  1624. RasFramingInfo.RFI_MaxRecvFrameSize = LcpDefault.MRU;
  1625. }
  1626. if ( pLcpCb->Local.Work.Negotiate & LCP_N_ACCM )
  1627. {
  1628. RasFramingInfo.RFI_RecvACCM = pLcpCb->Local.Work.ACCM;
  1629. }
  1630. else
  1631. {
  1632. RasFramingInfo.RFI_RecvACCM = LcpDefault.ACCM;
  1633. }
  1634. if ( pLcpCb->Local.Work.Negotiate & LCP_N_PFC )
  1635. {
  1636. RasFramingInfo.RFI_RecvFramingBits |= PPP_COMPRESS_PROTOCOL_FIELD;
  1637. }
  1638. if ( pLcpCb->Local.Work.Negotiate & LCP_N_ACFC )
  1639. {
  1640. RasFramingInfo.RFI_RecvFramingBits |= PPP_COMPRESS_ADDRESS_CONTROL;
  1641. }
  1642. if ( pLcpCb->Local.Work.Negotiate & LCP_N_SHORT_SEQ )
  1643. {
  1644. RasFramingInfo.RFI_RecvFramingBits |= PPP_SHORT_SEQUENCE_HDR_FORMAT;
  1645. }
  1646. if ( pLcpCb->Local.Work.Negotiate & LCP_N_AUTHENT )
  1647. {
  1648. LocalAuthProtocol = pLcpCb->Local.Work.AP;
  1649. }
  1650. else
  1651. {
  1652. LocalAuthProtocol = LcpDefault.AP;
  1653. pLcpCb->Local.Work.AP = LcpDefault.AP;
  1654. }
  1655. if ( pLcpCb->Local.Work.Negotiate & LCP_N_MAGIC )
  1656. {
  1657. LocalMagicNumber = pLcpCb->Local.Work.MagicNumber;
  1658. }
  1659. else
  1660. {
  1661. LocalMagicNumber = LcpDefault.MagicNumber;
  1662. }
  1663. if ( pLcpCb->Local.Work.Negotiate & LCP_N_MRRU )
  1664. {
  1665. RasFramingInfo.RFI_RecvFramingBits |= PPP_MULTILINK_FRAMING;
  1666. RasFramingInfo.RFI_MaxRRecvFrameSize = pLcpCb->Local.Work.MRRU;
  1667. }
  1668. else
  1669. {
  1670. RasFramingInfo.RFI_MaxRRecvFrameSize = LcpDefault.MRRU;
  1671. }
  1672. if ( ( pLcpCb->Local.Work.Negotiate & LCP_N_LINK_DISCRIM ) &&
  1673. ( pLcpCb->Remote.Work.Negotiate & LCP_N_LINK_DISCRIM ) )
  1674. {
  1675. pPcb->pBcb->fFlags |= BCBFLAG_CAN_DO_BAP;
  1676. }
  1677. RasFramingInfo.RFI_RecvFramingBits |= PPP_FRAMING;
  1678. PppLog( 1, "LCP Local Options-------------");
  1679. PppLog( 1,
  1680. "\tMRU=%d,ACCM=%d,Auth=%x,MagicNumber=%d,PFC=%s,ACFC=%s",
  1681. RasFramingInfo.RFI_MaxRecvFrameSize, RasFramingInfo.RFI_RecvACCM,
  1682. LocalAuthProtocol, LocalMagicNumber,
  1683. (RasFramingInfo.RFI_RecvFramingBits & PPP_COMPRESS_PROTOCOL_FIELD)
  1684. ? "ON" : "OFF",
  1685. ( RasFramingInfo.RFI_RecvFramingBits & PPP_COMPRESS_ADDRESS_CONTROL )
  1686. ? "ON" : "OFF" );
  1687. PppLog( 1, "\tRecv Framing = %s,SSHF=%s,MRRU=%d,LinkDiscrim=%x,BAP=%s",
  1688. ( RasFramingInfo.RFI_RecvFramingBits & PPP_MULTILINK_FRAMING )
  1689. ? "PPP Multilink" : "PPP",
  1690. ( RasFramingInfo.RFI_RecvFramingBits & PPP_SHORT_SEQUENCE_HDR_FORMAT)
  1691. ? "ON" : "OFF",
  1692. RasFramingInfo.RFI_MaxRRecvFrameSize,
  1693. pLcpCb->Local.Work.dwLinkDiscriminator,
  1694. pPcb->pBcb->fFlags & BCBFLAG_CAN_DO_BAP ? "ON" : "OFF");
  1695. if ( pLcpCb->Local.Work.Negotiate & LCP_N_ENDPOINT )
  1696. {
  1697. PppLog( 1, "\tED Class = %d, ED Value = %0*x%0*x%0*x%0*x%0*x",
  1698. *(pLcpCb->Local.Work.EndpointDiscr),
  1699. 8,WireToHostFormat32(pLcpCb->Local.Work.EndpointDiscr+1),
  1700. 8,WireToHostFormat32(pLcpCb->Local.Work.EndpointDiscr+5),
  1701. 8,WireToHostFormat32(pLcpCb->Local.Work.EndpointDiscr+9),
  1702. 8,WireToHostFormat32(pLcpCb->Local.Work.EndpointDiscr+13),
  1703. 8,WireToHostFormat32(pLcpCb->Local.Work.EndpointDiscr+17) );
  1704. }
  1705. if ( pLcpCb->Remote.Work.Negotiate & LCP_N_MRU )
  1706. {
  1707. RasFramingInfo.RFI_MaxSendFrameSize = pLcpCb->Remote.Work.MRU;
  1708. }
  1709. else
  1710. {
  1711. RasFramingInfo.RFI_MaxSendFrameSize = LcpDefault.MRU;
  1712. pLcpCb->Remote.Work.MRU = LcpDefault.MRU;
  1713. }
  1714. if ( pLcpCb->Remote.Work.Negotiate & LCP_N_ACCM )
  1715. {
  1716. RasFramingInfo.RFI_SendACCM = pLcpCb->Remote.Work.ACCM;
  1717. }
  1718. else
  1719. {
  1720. RasFramingInfo.RFI_SendACCM = LcpDefault.ACCM;
  1721. }
  1722. if ( pLcpCb->Remote.Work.Negotiate & LCP_N_PFC )
  1723. {
  1724. RasFramingInfo.RFI_SendFramingBits |= PPP_COMPRESS_PROTOCOL_FIELD;
  1725. }
  1726. if ( pLcpCb->Remote.Work.Negotiate & LCP_N_ACFC )
  1727. {
  1728. RasFramingInfo.RFI_SendFramingBits |= PPP_COMPRESS_ADDRESS_CONTROL;
  1729. }
  1730. if ( pLcpCb->Remote.Work.Negotiate & LCP_N_SHORT_SEQ )
  1731. {
  1732. RasFramingInfo.RFI_SendFramingBits |= PPP_SHORT_SEQUENCE_HDR_FORMAT;
  1733. }
  1734. if ( pLcpCb->Remote.Work.Negotiate & LCP_N_AUTHENT )
  1735. {
  1736. RemoteAuthProtocol = pLcpCb->Remote.Work.AP;
  1737. }
  1738. else
  1739. {
  1740. RemoteAuthProtocol = LcpDefault.AP;
  1741. pLcpCb->Remote.Work.AP = LcpDefault.AP;
  1742. }
  1743. if ( pLcpCb->Remote.Work.Negotiate & LCP_N_MAGIC )
  1744. {
  1745. RemoteMagicNumber = pLcpCb->Remote.Work.MagicNumber;
  1746. }
  1747. else
  1748. {
  1749. RemoteMagicNumber = LcpDefault.MagicNumber;
  1750. }
  1751. if ( pLcpCb->Remote.Work.Negotiate & LCP_N_MRRU )
  1752. {
  1753. RasFramingInfo.RFI_SendFramingBits |= PPP_MULTILINK_FRAMING;
  1754. RasFramingInfo.RFI_MaxRSendFrameSize = pLcpCb->Remote.Work.MRRU;
  1755. }
  1756. else
  1757. {
  1758. RasFramingInfo.RFI_MaxRSendFrameSize = LcpDefault.MRRU;
  1759. }
  1760. RasFramingInfo.RFI_SendFramingBits |= PPP_FRAMING;
  1761. PppLog( 1, "LCP Remote Options-------------");
  1762. PppLog( 1, "\tMRU=%d,ACCM=%d,Auth=%x,MagicNumber=%d,PFC=%s,ACFC=%s",
  1763. RasFramingInfo.RFI_MaxSendFrameSize, RasFramingInfo.RFI_SendACCM,
  1764. RemoteAuthProtocol, RemoteMagicNumber,
  1765. (RasFramingInfo.RFI_SendFramingBits & PPP_COMPRESS_PROTOCOL_FIELD)
  1766. ? "ON" : "OFF",
  1767. (RasFramingInfo.RFI_SendFramingBits & PPP_COMPRESS_ADDRESS_CONTROL)
  1768. ? "ON" : "OFF" );
  1769. PppLog( 1, "\tSend Framing = %s,SSHF=%s,MRRU=%d,LinkDiscrim=%x",
  1770. ( RasFramingInfo.RFI_SendFramingBits & PPP_MULTILINK_FRAMING )
  1771. ? "PPP Multilink" : "PPP",
  1772. ( RasFramingInfo.RFI_SendFramingBits & PPP_SHORT_SEQUENCE_HDR_FORMAT)
  1773. ? "ON" : "OFF",
  1774. RasFramingInfo.RFI_MaxRSendFrameSize,
  1775. pLcpCb->Remote.Work.dwLinkDiscriminator );
  1776. if ( pLcpCb->Remote.Work.Negotiate & LCP_N_ENDPOINT )
  1777. {
  1778. PppLog( 1, "\tED Class = %d, ED Value = %0*x%0*x%0*x%0*x%0*x",
  1779. *(pLcpCb->Remote.Work.EndpointDiscr),
  1780. 8,WireToHostFormat32(pLcpCb->Remote.Work.EndpointDiscr+1),
  1781. 8,WireToHostFormat32(pLcpCb->Remote.Work.EndpointDiscr+5),
  1782. 8,WireToHostFormat32(pLcpCb->Remote.Work.EndpointDiscr+9),
  1783. 8,WireToHostFormat32(pLcpCb->Remote.Work.EndpointDiscr+13),
  1784. 8,WireToHostFormat32(pLcpCb->Remote.Work.EndpointDiscr+17));
  1785. }
  1786. if ( pLcpCb->Local.Work.Negotiate & LCP_N_MRRU )
  1787. {
  1788. pPcb->fFlags |= PCBFLAG_CAN_BE_BUNDLED;
  1789. }
  1790. else
  1791. {
  1792. pPcb->fFlags &= ~PCBFLAG_CAN_BE_BUNDLED;
  1793. }
  1794. if ( ( pLcpCb->Local.Work.Negotiate & LCP_N_CALLBACK ) ||
  1795. ( pLcpCb->Remote.Work.Negotiate & LCP_N_CALLBACK ) )
  1796. {
  1797. pPcb->fFlags |= PCBFLAG_NEGOTIATE_CALLBACK;
  1798. }
  1799. else
  1800. {
  1801. pPcb->fFlags &= ~PCBFLAG_NEGOTIATE_CALLBACK;
  1802. }
  1803. dwRetCode = RasPortSetFramingEx( pLcpCb->hPort, &RasFramingInfo );
  1804. //
  1805. // This is a benign error and should not be logged.
  1806. //
  1807. if ( dwRetCode == ERROR_NOT_CONNECTED )
  1808. {
  1809. return( NO_ERROR );
  1810. }
  1811. else
  1812. {
  1813. return( dwRetCode );
  1814. }
  1815. }
  1816. //**
  1817. //
  1818. // Call: LcpThisLayerDown
  1819. //
  1820. // Returns: NO_ERROR - Success
  1821. // Non-zero return from RasPortSetFraming - Failure
  1822. //
  1823. // Description: Simply sets the framing parameters to the default values,
  1824. // ie. ACCM = 0xFFFFFFFF, everything else is zeros.
  1825. //
  1826. DWORD
  1827. LcpThisLayerDown(
  1828. IN VOID * pWorkBuffer
  1829. )
  1830. {
  1831. DWORD dwRetCode;
  1832. RAS_FRAMING_INFO RasFramingInfo;
  1833. LCPCB * pLcpCb = (LCPCB *)pWorkBuffer;
  1834. ZeroMemory( &RasFramingInfo, sizeof( RasFramingInfo ) );
  1835. RasFramingInfo.RFI_RecvACCM = LcpDefault.ACCM;
  1836. RasFramingInfo.RFI_SendACCM = LcpDefault.ACCM;
  1837. RasFramingInfo.RFI_SendFramingBits = PPP_FRAMING;
  1838. RasFramingInfo.RFI_RecvFramingBits = PPP_FRAMING;
  1839. dwRetCode = RasPortSetFramingEx( pLcpCb->hPort, &RasFramingInfo );
  1840. if ( dwRetCode == ERROR_NOT_CONNECTED )
  1841. {
  1842. return( NO_ERROR );
  1843. }
  1844. else
  1845. {
  1846. return( dwRetCode );
  1847. }
  1848. }
  1849. //**
  1850. //
  1851. // Call: LcpGetNegotiatedInfo
  1852. //
  1853. // Returns: NO_ERROR - Success
  1854. // Non-zero returns - Failure
  1855. //
  1856. // Description:
  1857. //
  1858. DWORD
  1859. LcpGetNegotiatedInfo(
  1860. IN VOID* pWorkBuffer,
  1861. OUT PPP_LCP_RESULT * pLcpResult
  1862. )
  1863. {
  1864. LCPCB * pLcpCb = (LCPCB *)pWorkBuffer;
  1865. if ( pLcpCb->Local.Work.Negotiate & LCP_N_MRRU )
  1866. {
  1867. pLcpResult->dwLocalFramingType |= PPP_MULTILINK_FRAMING;
  1868. }
  1869. else
  1870. {
  1871. pLcpResult->dwLocalFramingType |= PPP_FRAMING;
  1872. }
  1873. if ( pLcpCb->Local.Work.Negotiate & LCP_N_AUTHENT )
  1874. {
  1875. pLcpResult->dwLocalAuthProtocol = pLcpCb->Local.Work.AP;
  1876. }
  1877. else
  1878. {
  1879. pLcpResult->dwLocalAuthProtocol = LcpDefault.AP;
  1880. }
  1881. pLcpResult->dwLocalOptions = 0;
  1882. if ( pLcpCb->Local.Work.Negotiate & LCP_N_PFC )
  1883. {
  1884. pLcpResult->dwLocalOptions |= PPPLCPO_PFC;
  1885. }
  1886. if ( pLcpCb->Local.Work.Negotiate & LCP_N_ACFC )
  1887. {
  1888. pLcpResult->dwLocalOptions |= PPPLCPO_ACFC;
  1889. }
  1890. if ( pLcpCb->Local.Work.Negotiate & LCP_N_SHORT_SEQ )
  1891. {
  1892. pLcpResult->dwLocalOptions |= PPPLCPO_SSHF;
  1893. }
  1894. if ( ( pLcpCb->Local.Work.APDataSize > 0 ) &&
  1895. ( pLcpCb->Local.Work.APDataSize < 5 ) )
  1896. {
  1897. if ( pLcpCb->Local.Work.APDataSize == 1 )
  1898. {
  1899. pLcpResult->dwLocalAuthProtocolData =
  1900. (DWORD)*(pLcpCb->Local.Work.pAPData);
  1901. }
  1902. else if ( pLcpCb->Local.Work.APDataSize == 2 )
  1903. {
  1904. pLcpResult->dwLocalAuthProtocolData =
  1905. WireToHostFormat16( pLcpCb->Local.Work.pAPData );
  1906. }
  1907. else
  1908. {
  1909. pLcpResult->dwLocalAuthProtocolData =
  1910. WireToHostFormat32( pLcpCb->Local.Work.pAPData );
  1911. }
  1912. }
  1913. else
  1914. {
  1915. pLcpResult->dwLocalAuthProtocolData = 0;
  1916. }
  1917. if ( pLcpCb->Remote.Work.Negotiate & LCP_N_AUTHENT )
  1918. {
  1919. pLcpResult->dwRemoteAuthProtocol = pLcpCb->Remote.Work.AP;
  1920. }
  1921. else
  1922. {
  1923. pLcpResult->dwRemoteAuthProtocol = LcpDefault.AP;
  1924. }
  1925. if ( pLcpCb->Remote.Work.Negotiate & LCP_N_MRRU )
  1926. {
  1927. pLcpResult->dwRemoteFramingType |= PPP_MULTILINK_FRAMING;
  1928. }
  1929. else
  1930. {
  1931. pLcpResult->dwRemoteFramingType |= PPP_FRAMING;
  1932. }
  1933. pLcpResult->dwRemoteOptions = 0;
  1934. if ( pLcpCb->Remote.Work.Negotiate & LCP_N_PFC )
  1935. {
  1936. pLcpResult->dwRemoteOptions |= PPPLCPO_PFC;
  1937. }
  1938. if ( pLcpCb->Remote.Work.Negotiate & LCP_N_ACFC )
  1939. {
  1940. pLcpResult->dwRemoteOptions |= PPPLCPO_ACFC;
  1941. }
  1942. if ( pLcpCb->Remote.Work.Negotiate & LCP_N_SHORT_SEQ )
  1943. {
  1944. pLcpResult->dwRemoteOptions |= PPPLCPO_SSHF;
  1945. }
  1946. if ( ( pLcpCb->Remote.Work.APDataSize > 0 ) &&
  1947. ( pLcpCb->Remote.Work.APDataSize < 5 ) )
  1948. {
  1949. if ( pLcpCb->Remote.Work.APDataSize == 1 )
  1950. {
  1951. pLcpResult->dwRemoteAuthProtocolData =
  1952. (DWORD)*(pLcpCb->Remote.Work.pAPData);
  1953. }
  1954. else if ( pLcpCb->Remote.Work.APDataSize == 2 )
  1955. {
  1956. pLcpResult->dwRemoteAuthProtocolData =
  1957. WireToHostFormat16( pLcpCb->Remote.Work.pAPData );
  1958. }
  1959. else
  1960. {
  1961. pLcpResult->dwRemoteAuthProtocolData =
  1962. WireToHostFormat32( pLcpCb->Remote.Work.pAPData );
  1963. }
  1964. }
  1965. else
  1966. {
  1967. pLcpResult->dwRemoteAuthProtocolData = 0;
  1968. }
  1969. return( NO_ERROR );
  1970. }
  1971. //**
  1972. //
  1973. // Call: LcpGetInfo
  1974. //
  1975. // Returns: NO_ERROR - Success
  1976. // ERROR_INVALID_PARAMETER - Protocol id is unrecogized
  1977. //
  1978. // Description: This entry point is called for get all information for the
  1979. // control protocol in this module.
  1980. //
  1981. DWORD
  1982. LcpGetInfo(
  1983. IN DWORD dwProtocolId,
  1984. OUT PPPCP_INFO* pCpInfo
  1985. )
  1986. {
  1987. if ( dwProtocolId != PPP_LCP_PROTOCOL )
  1988. return( ERROR_INVALID_PARAMETER );
  1989. ZeroMemory( pCpInfo, sizeof( PPPCP_INFO ) );
  1990. pCpInfo->Protocol = PPP_LCP_PROTOCOL;
  1991. pCpInfo->Recognize = TIME_REMAINING + 1;
  1992. pCpInfo->RasCpBegin = LcpBegin;
  1993. pCpInfo->RasCpEnd = LcpEnd;
  1994. pCpInfo->RasCpReset = LcpReset;
  1995. pCpInfo->RasCpThisLayerStarted = LcpThisLayerStarted;
  1996. pCpInfo->RasCpThisLayerFinished = LcpThisLayerFinished;
  1997. pCpInfo->RasCpThisLayerUp = LcpThisLayerUp;
  1998. pCpInfo->RasCpThisLayerDown = LcpThisLayerDown;
  1999. pCpInfo->RasCpMakeConfigRequest = LcpMakeConfigRequest;
  2000. pCpInfo->RasCpMakeConfigResult = LcpMakeConfigResult;
  2001. pCpInfo->RasCpConfigAckReceived = LcpConfigAckReceived;
  2002. pCpInfo->RasCpConfigNakReceived = LcpConfigNakReceived;
  2003. pCpInfo->RasCpConfigRejReceived = LcpConfigRejReceived;
  2004. pCpInfo->RasCpGetNegotiatedInfo = LcpGetNegotiatedInfo;
  2005. return( NO_ERROR );
  2006. }