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.

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