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.

1835 lines
42 KiB

  1. /********************************************************************/
  2. /** Copyright(c) 1989 Microsoft Corporation. **/
  3. /********************************************************************/
  4. //***
  5. //
  6. // Filename: receive.c
  7. //
  8. // Description: This module contains code to handle all packets received.
  9. //
  10. // History:
  11. // Oct 25,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 <mprlog.h>
  25. #include <rasman.h>
  26. #include <rtutils.h>
  27. #include <rasppp.h>
  28. #include <pppcp.h>
  29. #include <ppp.h>
  30. #include <smaction.h>
  31. #include <smevents.h>
  32. #include <receive.h>
  33. #include <auth.h>
  34. #include <lcp.h>
  35. #include <timer.h>
  36. #include <util.h>
  37. #include <worker.h>
  38. #define INCL_RASAUTHATTRIBUTES
  39. #include <ppputil.h>
  40. //**
  41. //
  42. // Call: ReceiveConfigReq
  43. //
  44. // Returns: None.
  45. //
  46. // Description: Handles an incomming CONFIG_REQ packet and related state
  47. // transitions.
  48. //
  49. VOID
  50. ReceiveConfigReq(
  51. IN PCB * pPcb,
  52. IN DWORD CpIndex,
  53. IN CPCB * pCpCb,
  54. IN PPP_CONFIG * pRecvConfig
  55. )
  56. {
  57. PPP_CONFIG * pSendConfig = (PPP_CONFIG*)(pPcb->pSendBuf->Information);
  58. BOOL fAcked;
  59. switch( pCpCb->State )
  60. {
  61. case FSM_OPENED:
  62. if ( !FsmThisLayerDown( pPcb, CpIndex ) )
  63. return;
  64. if ( !FsmSendConfigReq( pPcb, CpIndex, FALSE ) )
  65. return;
  66. if( !FsmSendConfigResult( pPcb, CpIndex, pRecvConfig, &fAcked ) )
  67. return;
  68. pCpCb->State = ( fAcked ) ? FSM_ACK_SENT : FSM_REQ_SENT;
  69. break;
  70. case FSM_STOPPED:
  71. InitRestartCounters( pPcb, pCpCb );
  72. if ( !FsmSendConfigReq( pPcb, CpIndex, FALSE ) )
  73. return;
  74. //
  75. // Fallthru
  76. //
  77. case FSM_REQ_SENT:
  78. case FSM_ACK_SENT:
  79. if ( !FsmSendConfigResult( pPcb, CpIndex, pRecvConfig, &fAcked ) )
  80. return;
  81. pCpCb->State = ( fAcked ) ? FSM_ACK_SENT : FSM_REQ_SENT;
  82. break;
  83. case FSM_ACK_RCVD:
  84. if ( !FsmSendConfigResult( pPcb, CpIndex, pRecvConfig, &fAcked ) )
  85. return;
  86. if( fAcked )
  87. {
  88. pCpCb->State = FSM_OPENED;
  89. FsmThisLayerUp( pPcb, CpIndex );
  90. }
  91. break;
  92. case FSM_CLOSED:
  93. FsmSendTermAck( pPcb, CpIndex, pRecvConfig );
  94. break;
  95. case FSM_CLOSING:
  96. case FSM_STOPPING:
  97. break;
  98. case FSM_STARTING:
  99. case FSM_INITIAL:
  100. default:
  101. PPP_ASSERT( pCpCb->State < 10 );
  102. PppLog(2,"Illegal transition->ConfigReq received while in %s state",
  103. FsmStates[pCpCb->State] );
  104. break;
  105. }
  106. }
  107. //**
  108. //
  109. // Call: ReceiveConfigAck
  110. //
  111. // Returns: none.
  112. //
  113. // Description: Handles an incomming CONFIG_ACK packet and related state
  114. // transitions.
  115. //
  116. VOID
  117. ReceiveConfigAck(
  118. IN PCB * pPcb,
  119. IN DWORD CpIndex,
  120. IN CPCB * pCpCb,
  121. IN PPP_CONFIG * pRecvConfig
  122. )
  123. {
  124. //
  125. // The Id of the Ack HAS to match the Id of the last request sent
  126. // If it is different, then we should silently discard it.
  127. //
  128. if ( pRecvConfig->Id != pCpCb->LastId )
  129. {
  130. PppLog(1,
  131. "Config Ack rcvd. on port %d silently discarded. Invalid Id",
  132. pPcb->hPort );
  133. return;
  134. }
  135. switch( pCpCb->State )
  136. {
  137. case FSM_REQ_SENT:
  138. if ( !FsmConfigResultReceived( pPcb, CpIndex, pRecvConfig ) )
  139. return;
  140. RemoveFromTimerQ( pPcb->dwPortId,
  141. pRecvConfig->Id,
  142. CpTable[CpIndex].CpInfo.Protocol,
  143. FALSE,
  144. TIMER_EVENT_TIMEOUT );
  145. InitRestartCounters( pPcb, pCpCb );
  146. pCpCb->State = FSM_ACK_RCVD;
  147. break;
  148. case FSM_ACK_SENT:
  149. if ( !FsmConfigResultReceived( pPcb, CpIndex, pRecvConfig ) )
  150. return;
  151. RemoveFromTimerQ( pPcb->dwPortId,
  152. pRecvConfig->Id,
  153. CpTable[CpIndex].CpInfo.Protocol,
  154. FALSE,
  155. TIMER_EVENT_TIMEOUT );
  156. InitRestartCounters( pPcb, pCpCb );
  157. pCpCb->State = FSM_OPENED;
  158. FsmThisLayerUp( pPcb, CpIndex );
  159. break;
  160. case FSM_OPENED:
  161. RemoveFromTimerQ( pPcb->dwPortId,
  162. pRecvConfig->Id,
  163. CpTable[CpIndex].CpInfo.Protocol,
  164. FALSE,
  165. TIMER_EVENT_TIMEOUT );
  166. if ( !FsmThisLayerDown( pPcb, CpIndex ) )
  167. return;
  168. //
  169. // Fallthru
  170. //
  171. case FSM_ACK_RCVD:
  172. if ( !FsmSendConfigReq( pPcb, CpIndex, FALSE ) )
  173. return;
  174. pCpCb->State = FSM_REQ_SENT;
  175. break;
  176. case FSM_CLOSED:
  177. case FSM_STOPPED:
  178. RemoveFromTimerQ( pPcb->dwPortId,
  179. pRecvConfig->Id,
  180. CpTable[CpIndex].CpInfo.Protocol,
  181. FALSE,
  182. TIMER_EVENT_TIMEOUT );
  183. //
  184. // Out of Sync; kill the remote
  185. //
  186. FsmSendTermAck( pPcb, CpIndex, pRecvConfig );
  187. break;
  188. case FSM_CLOSING:
  189. case FSM_STOPPING:
  190. //
  191. // We are attempting to close connection
  192. // wait for timeout to resend a Terminate Request
  193. //
  194. break;
  195. case FSM_STARTING:
  196. case FSM_INITIAL:
  197. default:
  198. RemoveFromTimerQ( pPcb->dwPortId,
  199. pRecvConfig->Id,
  200. CpTable[CpIndex].CpInfo.Protocol,
  201. FALSE,
  202. TIMER_EVENT_TIMEOUT );
  203. PPP_ASSERT( pCpCb->State < 10 );
  204. PppLog(2,"Illegal transition->ConfigAck received while in %s state",
  205. FsmStates[pCpCb->State] );
  206. break;
  207. }
  208. }
  209. //**
  210. //
  211. // Call: ReceiveConfigNakRej
  212. //
  213. // Returns: none.
  214. //
  215. // Description: Handles an incomming CONFIG_NAK or CONFIF_REJ packet and
  216. // related state transitions.
  217. //
  218. VOID
  219. ReceiveConfigNakRej(
  220. IN PCB * pPcb,
  221. IN DWORD CpIndex,
  222. IN CPCB * pCpCb,
  223. IN PPP_CONFIG * pRecvConfig
  224. )
  225. {
  226. //
  227. // The Id of the Nak/Rej HAS to match the Id of the last request sent
  228. // If it is different, then we should silently discard it.
  229. //
  230. if ( pRecvConfig->Id != pCpCb->LastId )
  231. {
  232. PppLog(1,"Config Nak/Rej on port %d silently discarded. Invalid Id",
  233. pPcb->hPort );
  234. return;
  235. }
  236. switch( pCpCb->State )
  237. {
  238. case FSM_REQ_SENT:
  239. case FSM_ACK_SENT:
  240. if ( !FsmConfigResultReceived( pPcb, CpIndex, pRecvConfig ) )
  241. return;
  242. RemoveFromTimerQ( pPcb->dwPortId,
  243. pRecvConfig->Id,
  244. CpTable[CpIndex].CpInfo.Protocol,
  245. FALSE,
  246. TIMER_EVENT_TIMEOUT );
  247. InitRestartCounters( pPcb, pCpCb );
  248. if ( !FsmSendConfigReq( pPcb, CpIndex, FALSE ) )
  249. return;
  250. break;
  251. case FSM_OPENED:
  252. RemoveFromTimerQ( pPcb->dwPortId,
  253. pRecvConfig->Id,
  254. CpTable[CpIndex].CpInfo.Protocol,
  255. FALSE,
  256. TIMER_EVENT_TIMEOUT );
  257. if ( !FsmThisLayerDown( pPcb, CpIndex ) )
  258. return;
  259. //
  260. // Fallthru
  261. //
  262. case FSM_ACK_RCVD:
  263. if ( !FsmSendConfigReq( pPcb, CpIndex, FALSE ) )
  264. return;
  265. pCpCb->State = FSM_REQ_SENT;
  266. break;
  267. case FSM_CLOSED:
  268. case FSM_STOPPED:
  269. RemoveFromTimerQ( pPcb->dwPortId,
  270. pRecvConfig->Id,
  271. CpTable[CpIndex].CpInfo.Protocol,
  272. FALSE,
  273. TIMER_EVENT_TIMEOUT );
  274. //
  275. // Out of Sync; kill the remote
  276. //
  277. FsmSendTermAck( pPcb, CpIndex, pRecvConfig );
  278. break;
  279. case FSM_CLOSING:
  280. case FSM_STOPPING:
  281. //
  282. // We are attempting to close connection
  283. // wait for timeout to resend a Terminate Request
  284. //
  285. break;
  286. case FSM_STARTING:
  287. case FSM_INITIAL:
  288. default:
  289. RemoveFromTimerQ( pPcb->dwPortId,
  290. pRecvConfig->Id,
  291. CpTable[CpIndex].CpInfo.Protocol,
  292. FALSE,
  293. TIMER_EVENT_TIMEOUT );
  294. PPP_ASSERT( pCpCb->State < 10 );
  295. PppLog(2,"Illegal transition->CfgNakRej received while in %s state",
  296. FsmStates[pCpCb->State] );
  297. break;
  298. }
  299. }
  300. //**
  301. //
  302. // Call: ReceiveTermReq
  303. //
  304. // Returns: none
  305. //
  306. // Description: Handles an incomming TERM_REQ packet and
  307. // related state transitions.
  308. //
  309. VOID
  310. ReceiveTermReq(
  311. IN PCB * pPcb,
  312. IN DWORD CpIndex,
  313. IN CPCB * pCpCb,
  314. IN PPP_CONFIG * pConfig
  315. )
  316. {
  317. //
  318. // We are shutting down so do not resend any outstanding request.
  319. //
  320. RemoveFromTimerQ( pPcb->dwPortId,
  321. pCpCb->LastId,
  322. CpTable[CpIndex].CpInfo.Protocol,
  323. FALSE,
  324. TIMER_EVENT_TIMEOUT );
  325. if ( CpIndex == LCP_INDEX )
  326. {
  327. //
  328. // If we are receiving a terminate request, remove any hangup event
  329. // that we may have put into the timer queue if there was a previous
  330. // LCP TermReq sent.
  331. RemoveFromTimerQ( pPcb->dwPortId,
  332. 0,
  333. 0,
  334. FALSE,
  335. TIMER_EVENT_HANGUP );
  336. }
  337. switch( pCpCb->State )
  338. {
  339. case FSM_OPENED:
  340. if ( !FsmThisLayerDown( pPcb, CpIndex ) )
  341. return;
  342. //
  343. // Zero restart counters
  344. //
  345. pCpCb->ConfigRetryCount = 0;
  346. pCpCb->TermRetryCount = 0;
  347. pCpCb->NakRetryCount = 0;
  348. pCpCb->RejRetryCount = 0;
  349. FsmSendTermAck( pPcb, CpIndex, pConfig );
  350. pCpCb->State = FSM_STOPPING;
  351. break;
  352. case FSM_ACK_RCVD:
  353. case FSM_ACK_SENT:
  354. case FSM_REQ_SENT:
  355. FsmSendTermAck( pPcb, CpIndex, pConfig );
  356. pCpCb->State = FSM_REQ_SENT;
  357. break;
  358. case FSM_CLOSED:
  359. case FSM_CLOSING:
  360. case FSM_STOPPED:
  361. case FSM_STOPPING:
  362. FsmSendTermAck( pPcb, CpIndex, pConfig );
  363. break;
  364. case FSM_STARTING:
  365. case FSM_INITIAL:
  366. default:
  367. PPP_ASSERT( pCpCb->State < 10 );
  368. PppLog(2,"Illegal transition->CfgNakRej received while in %s state",
  369. FsmStates[pCpCb->State] );
  370. break;
  371. }
  372. if ( CpIndex == LCP_INDEX )
  373. {
  374. pPcb->fFlags |= PCBFLAG_RECVD_TERM_REQ;
  375. //
  376. // If we got a terminate request from the remote peer.
  377. //
  378. if ( pPcb->fFlags & PCBFLAG_DOING_CALLBACK ) {
  379. //
  380. // If we are the server side we need to tell the server
  381. // to callback.
  382. //
  383. if ( pPcb->fFlags & PCBFLAG_IS_SERVER ) {
  384. PPPDDM_CALLBACK_REQUEST PppDdmCallbackRequest;
  385. PppDdmCallbackRequest.fUseCallbackDelay = TRUE;
  386. PppDdmCallbackRequest.dwCallbackDelay =
  387. pPcb->ConfigInfo.dwCallbackDelay;
  388. strcpy( PppDdmCallbackRequest.szCallbackNumber,
  389. pPcb->szCallbackNumber );
  390. PppLog( 2, "Notifying server to callback at %s, delay = %d",
  391. PppDdmCallbackRequest.szCallbackNumber,
  392. PppDdmCallbackRequest.dwCallbackDelay );
  393. NotifyCaller( pPcb,
  394. PPPDDMMSG_CallbackRequest,
  395. &PppDdmCallbackRequest );
  396. }
  397. //
  398. // If we are the client?
  399. //
  400. }
  401. else
  402. {
  403. //
  404. // Check to see if the remote peer sent a Terminate Request reason
  405. //
  406. DWORD dwLength = WireToHostFormat16( pConfig->Length );
  407. LCPCB * pLcpCb = (LCPCB*)(pPcb->LcpCb.pWorkBuf);
  408. DWORD dwRetCode = ERROR_PPP_LCP_TERMINATED;
  409. if ( dwLength == PPP_CONFIG_HDR_LEN + 12 )
  410. {
  411. //
  412. // Check to see if this is our signature
  413. //
  414. if ( ( WireToHostFormat32( pConfig->Data ) ==
  415. pLcpCb->Remote.Work.MagicNumber )
  416. &&
  417. ( WireToHostFormat32( pConfig->Data + 4 ) == 3984756 ) )
  418. {
  419. dwRetCode = WireToHostFormat32( pConfig->Data + 8 );
  420. //
  421. // Should not be larger than the highest winerror.h
  422. //
  423. if ( dwRetCode > ERROR_DHCP_ADDRESS_CONFLICT )
  424. {
  425. //
  426. // Ignore this error
  427. //
  428. dwRetCode = ERROR_PPP_LCP_TERMINATED;
  429. }
  430. if ( dwRetCode == ERROR_NO_LOCAL_ENCRYPTION )
  431. {
  432. dwRetCode = ERROR_NO_REMOTE_ENCRYPTION;
  433. }
  434. else if ( dwRetCode == ERROR_NO_REMOTE_ENCRYPTION )
  435. {
  436. dwRetCode = ERROR_NO_LOCAL_ENCRYPTION;
  437. }
  438. }
  439. }
  440. if ( pCpCb->dwError == NO_ERROR )
  441. {
  442. pCpCb->dwError = dwRetCode;
  443. }
  444. if ( !( pPcb->fFlags & PCBFLAG_IS_SERVER ) )
  445. {
  446. NotifyCallerOfFailure( pPcb, pCpCb->dwError );
  447. //
  448. // If we are a client check to see if the server disconnected us
  449. // because of autodisconnect.
  450. //
  451. if ( ( dwRetCode == ERROR_IDLE_DISCONNECTED ) ||
  452. ( dwRetCode == ERROR_PPP_SESSION_TIMEOUT ) )
  453. {
  454. CHAR * pszPortName = pPcb->szPortName;
  455. PppLogInformation(
  456. ( dwRetCode == ERROR_IDLE_DISCONNECTED )
  457. ? ROUTERLOG_CLIENT_AUTODISCONNECT
  458. : ROUTERLOG_PPP_SESSION_TIMEOUT,
  459. 1,
  460. &pszPortName );
  461. }
  462. }
  463. //
  464. // If the remote LCP is terminating we MUST wait at least one
  465. // restart timer time period before we hangup.
  466. //
  467. InsertInTimerQ( pPcb->dwPortId,
  468. pPcb->hPort,
  469. 0,
  470. 0,
  471. FALSE,
  472. TIMER_EVENT_HANGUP,
  473. pPcb->RestartTimer );
  474. }
  475. }
  476. else
  477. {
  478. if ( pCpCb->dwError == NO_ERROR )
  479. {
  480. pCpCb->dwError = ERROR_PPP_NCP_TERMINATED;
  481. }
  482. FsmThisLayerFinished( pPcb, CpIndex, FALSE );
  483. }
  484. }
  485. //**
  486. //
  487. // Call: ReceiveTermAck
  488. //
  489. // Returns: none
  490. //
  491. // Description: Handles an incomming TERM_ACK packet and
  492. // related state transitions.
  493. //
  494. VOID
  495. ReceiveTermAck(
  496. IN PCB * pPcb,
  497. IN DWORD CpIndex,
  498. IN CPCB * pCpCb,
  499. IN PPP_CONFIG * pRecvConfig
  500. )
  501. {
  502. //
  503. // The Id of the Term Ack HAS to match the Id of the last request sent
  504. // If it is different, then we should silently discard it.
  505. //
  506. if ( pRecvConfig->Id != pCpCb->LastId )
  507. {
  508. PppLog(1,"Term Ack with on port %d silently discarded. Invalid Id",
  509. pPcb->hPort );
  510. return;
  511. }
  512. switch( pCpCb->State )
  513. {
  514. case FSM_OPENED:
  515. if ( !FsmThisLayerDown( pPcb, CpIndex ) )
  516. return;
  517. if ( !FsmSendConfigReq( pPcb, CpIndex, FALSE ) )
  518. return;
  519. pCpCb->State = FSM_REQ_SENT;
  520. break;
  521. case FSM_ACK_RCVD:
  522. pCpCb->State = FSM_REQ_SENT;
  523. break;
  524. case FSM_CLOSING:
  525. case FSM_STOPPING:
  526. //
  527. // Remove the timeout for this Id from the timer Q
  528. //
  529. RemoveFromTimerQ( pPcb->dwPortId,
  530. pRecvConfig->Id,
  531. CpTable[CpIndex].CpInfo.Protocol,
  532. FALSE,
  533. TIMER_EVENT_TIMEOUT );
  534. if ( !FsmThisLayerFinished( pPcb, CpIndex, TRUE ) )
  535. return;
  536. pCpCb->State = ( pCpCb->State == FSM_CLOSING ) ? FSM_CLOSED
  537. : FSM_STOPPED;
  538. break;
  539. case FSM_REQ_SENT:
  540. case FSM_ACK_SENT:
  541. case FSM_CLOSED:
  542. case FSM_STOPPED:
  543. break;
  544. case FSM_STARTING:
  545. case FSM_INITIAL:
  546. default:
  547. PPP_ASSERT( pCpCb->State < 10 );
  548. PppLog( 2,"Illegal transition->CfgNakRej received while in %s state",
  549. FsmStates[pCpCb->State] );
  550. break;
  551. }
  552. }
  553. //**
  554. //
  555. // Call: ReceiveUnknownCode
  556. //
  557. // Returns: none.
  558. //
  559. // Description: Handles a packet with an unknown/unrecognizable code and
  560. // related state transitions.
  561. //
  562. VOID
  563. ReceiveUnknownCode(
  564. IN PCB * pPcb,
  565. IN DWORD CpIndex,
  566. IN CPCB * pCpCb,
  567. IN PPP_CONFIG * pConfig
  568. )
  569. {
  570. PppLog( 2, "Received packet with unknown code %d", pConfig->Code );
  571. switch( pCpCb->State )
  572. {
  573. case FSM_STOPPED:
  574. case FSM_STOPPING:
  575. case FSM_OPENED:
  576. case FSM_ACK_SENT:
  577. case FSM_ACK_RCVD:
  578. case FSM_REQ_SENT:
  579. case FSM_CLOSING:
  580. case FSM_CLOSED:
  581. FsmSendCodeReject( pPcb, CpIndex, pConfig );
  582. break;
  583. case FSM_STARTING:
  584. case FSM_INITIAL:
  585. default:
  586. PPP_ASSERT( pCpCb->State < 10 );
  587. PppLog( 2, "Illegal transition->UnknownCode rcvd while in %s state",
  588. FsmStates[pCpCb->State] );
  589. break;
  590. }
  591. }
  592. //**
  593. //
  594. // Call: ReceiveDiscardReq
  595. //
  596. // Returns: none
  597. //
  598. // Description: Handles an incomming DISCARD_REQ packet and
  599. // related state transitions.
  600. //
  601. VOID
  602. ReceiveDiscardReq(
  603. IN PCB * pPcb,
  604. IN DWORD CpIndex,
  605. IN CPCB * pCpCb,
  606. IN PPP_CONFIG * pConfig
  607. )
  608. {
  609. //
  610. // Simply discard the packet.
  611. //
  612. PppLog( 2, "Illegal transition->Discard rqst rcvd while in %s state",
  613. FsmStates[pCpCb->State] );
  614. }
  615. //**
  616. //
  617. // Call: ReceiveEchoReq
  618. //
  619. // Returns: none
  620. //
  621. // Description: Handles an incomming ECHO_REQ packet and
  622. // related state transitions.
  623. //
  624. VOID
  625. ReceiveEchoReq(
  626. IN PCB * pPcb,
  627. IN DWORD CpIndex,
  628. IN CPCB * pCpCb,
  629. IN PPP_CONFIG * pConfig
  630. )
  631. {
  632. //
  633. // Silently discard this packet if LCP is not in an opened state
  634. //
  635. if ( !IsLcpOpened( pPcb ) )
  636. return;
  637. switch( pCpCb->State )
  638. {
  639. case FSM_STOPPED:
  640. case FSM_STOPPING:
  641. case FSM_ACK_SENT:
  642. case FSM_ACK_RCVD:
  643. case FSM_REQ_SENT:
  644. case FSM_CLOSING:
  645. case FSM_CLOSED:
  646. case FSM_STARTING:
  647. case FSM_INITIAL:
  648. break;
  649. case FSM_OPENED:
  650. FsmSendEchoReply( pPcb, CpIndex, pConfig );
  651. break;
  652. default:
  653. PPP_ASSERT( pCpCb->State < 10 );
  654. PppLog( 2, "Illegal transition->UnknownCode rcvd while in %s state",
  655. FsmStates[pCpCb->State] );
  656. break;
  657. }
  658. }
  659. //**
  660. //
  661. // Call: ReceiveEchoReply
  662. //
  663. // Returns: none
  664. //
  665. // Description: Handles an incomming ECHO_REPLY packet and
  666. // related state transitions. The only Echo request we send
  667. // is to calculate the link speed, so we assume that we get called
  668. // only when we receive the reply.
  669. //
  670. VOID
  671. ReceiveEchoReply(
  672. IN PCB * pPcb,
  673. IN DWORD CpIndex,
  674. IN CPCB * pCpCb,
  675. IN PPP_CONFIG * pConfig
  676. )
  677. {
  678. LCPCB * pLcpCb = (LCPCB*)(pPcb->LcpCb.pWorkBuf);
  679. DWORD dwLength = PPP_PACKET_HDR_LEN +
  680. WireToHostFormat16( pConfig->Length );
  681. if ( dwLength > LCP_DEFAULT_MRU )
  682. {
  683. dwLength = LCP_DEFAULT_MRU;
  684. }
  685. if ( dwLength < PPP_PACKET_HDR_LEN + PPP_CONFIG_HDR_LEN + 4 )
  686. {
  687. PppLog( 1, "Silently discarding invalid echo response packet on port=%d",
  688. pPcb->hPort );
  689. return;
  690. }
  691. //
  692. // Pass on the echo reply to whoever send the echo request.
  693. //
  694. if ( !(pPcb->fFlags & PCBFLAG_IS_SERVER) && ( RAS_DEVICE_TYPE(pPcb->dwDeviceType) == RDT_PPPoE) && pPcb->dwIdleBeforeEcho )
  695. {
  696. if ( pPcb->fEchoRequestSend )
  697. {
  698. //check to see if we are getting the same text back on the echo
  699. if ( !memcmp( pConfig->Data+ 4, PPP_DEF_ECHO_TEXT, strlen(PPP_DEF_ECHO_TEXT)) )
  700. {
  701. //got the echo response for our echo request
  702. //so reset the flag.
  703. pPcb->fEchoRequestSend = 0;
  704. pPcb->dwNumEchoResponseMissed = 0;
  705. }
  706. }
  707. }
  708. }
  709. //**
  710. //
  711. // Call: ReceiveCodeRej
  712. //
  713. // Returns: none
  714. //
  715. // Description: Handles an incomming CODE_REJ packet and
  716. // related state transitions.
  717. //
  718. VOID
  719. ReceiveCodeRej(
  720. IN PCB * pPcb,
  721. IN DWORD CpIndex,
  722. IN CPCB * pCpCb,
  723. IN PPP_CONFIG * pConfig
  724. )
  725. {
  726. pConfig = (PPP_CONFIG*)(pConfig->Data);
  727. PppLog( 2, "PPP Code Reject rcvd, rejected Code = %d", pConfig->Code );
  728. //
  729. // First check to see if these codes may be rejected without
  730. // affecting implementation. Permitted code rejects
  731. //
  732. if ( CpIndex == LCP_INDEX )
  733. {
  734. switch( pConfig->Code )
  735. {
  736. case CONFIG_REQ:
  737. case CONFIG_ACK:
  738. case CONFIG_NAK:
  739. case CONFIG_REJ:
  740. case TERM_REQ:
  741. case TERM_ACK:
  742. case CODE_REJ:
  743. case PROT_REJ:
  744. case ECHO_REQ:
  745. case ECHO_REPLY:
  746. case DISCARD_REQ:
  747. //
  748. // Unpermitted code rejects.
  749. //
  750. break;
  751. case IDENTIFICATION:
  752. case TIME_REMAINING:
  753. //
  754. // Turn these off.
  755. //
  756. pPcb->ConfigInfo.dwConfigMask &= (~PPPCFG_UseLcpExtensions);
  757. //
  758. // no break here no purpose.
  759. //
  760. default:
  761. //
  762. // Permitted code rejects, we can still work.
  763. //
  764. switch ( pCpCb->State )
  765. {
  766. case FSM_ACK_RCVD:
  767. pCpCb->State = FSM_REQ_SENT;
  768. break;
  769. default:
  770. break;
  771. }
  772. return;
  773. }
  774. }
  775. //
  776. // Log this error
  777. //
  778. //PPPLogEvent( PPP_EVENT_RECV_UNKNOWN_CODE, pConfig->Code );
  779. PppLog( 1, "Unpermitted code reject rcvd. on port %d", pPcb->hPort );
  780. //
  781. // Actually the remote side did not reject the protocol, it rejected
  782. // the code. But for all practical purposes we cannot talk with
  783. // the corresponding CP on the remote side. This is actually an
  784. // implementation error in the remote side.
  785. //
  786. pCpCb->dwError = ERROR_PPP_NOT_CONVERGING;
  787. RemoveFromTimerQ( pPcb->dwPortId,
  788. pCpCb->LastId,
  789. CpTable[CpIndex].CpInfo.Protocol,
  790. FALSE,
  791. TIMER_EVENT_TIMEOUT );
  792. switch ( pCpCb->State )
  793. {
  794. case FSM_CLOSING:
  795. if ( !FsmThisLayerFinished( pPcb, CpIndex, TRUE ) )
  796. return;
  797. pCpCb->State = FSM_CLOSED;
  798. break;
  799. case FSM_REQ_SENT:
  800. case FSM_ACK_RCVD:
  801. case FSM_ACK_SENT:
  802. case FSM_STOPPING:
  803. if ( !FsmThisLayerFinished( pPcb, CpIndex, TRUE ) )
  804. return;
  805. pCpCb->State = FSM_STOPPED;
  806. break;
  807. case FSM_OPENED:
  808. if ( !FsmThisLayerDown( pPcb, CpIndex ) )
  809. return;
  810. InitRestartCounters( pPcb, pCpCb );
  811. FsmSendTermReq( pPcb, CpIndex );
  812. pCpCb->State = FSM_STOPPING;
  813. break;
  814. case FSM_CLOSED:
  815. case FSM_STOPPED:
  816. break;
  817. case FSM_STARTING:
  818. case FSM_INITIAL:
  819. default:
  820. PPP_ASSERT( pCpCb->State < 10 );
  821. PppLog( 2, "Illegal transition->UnknownCode rcvd while in %s state",
  822. FsmStates[pCpCb->State] );
  823. break;
  824. }
  825. }
  826. //**
  827. //
  828. // Call: ReceiveProtocolRej
  829. //
  830. // Returns: none
  831. //
  832. // Description: Handles an incomming PROT_REJ packet and
  833. // related state transitions.
  834. //
  835. VOID
  836. ReceiveProtocolRej(
  837. IN PCB * pPcb,
  838. IN PPP_PACKET * pPacket
  839. )
  840. {
  841. PPP_CONFIG * pRecvConfig = (PPP_CONFIG *)(pPacket->Information);
  842. DWORD dwProtocol = WireToHostFormat16( pRecvConfig->Data );
  843. CPCB * pCpCb;
  844. DWORD CpIndex;
  845. PppLog( 2, "PPP Protocol Reject, Protocol = %x", dwProtocol );
  846. CpIndex = GetCpIndexFromProtocol( dwProtocol );
  847. if ( CpIndex == (DWORD)-1 )
  848. {
  849. return;
  850. }
  851. //
  852. // "Protocol Reject" in the middle of LCP (RXJ- in state 2-9) should cause
  853. // immediate termination.
  854. //
  855. if ( LCP_INDEX == CpIndex )
  856. {
  857. pPcb->LcpCb.dwError = ERROR_PPP_NOT_CONVERGING;
  858. NotifyCallerOfFailure( pPcb, pPcb->LcpCb.dwError );
  859. return;
  860. }
  861. //
  862. // If LCP is not in the opened state we silently discard this packet
  863. //
  864. if ( !IsLcpOpened( pPcb ) )
  865. {
  866. PppLog(1,"Protocol Rej silently discarded on port %d. Lcp not open",
  867. pPcb->hPort );
  868. return;
  869. }
  870. //
  871. // If remote peer rejected an Authentication protocol, then bring down
  872. // the link (LCP) since this should never happen.
  873. //
  874. if ( IsCpIndexOfAp( CpIndex ) )
  875. {
  876. CpIndex = LCP_INDEX;
  877. pCpCb = GetPointerToCPCB( pPcb, LCP_INDEX );
  878. pCpCb->dwError = ERROR_AUTH_PROTOCOL_REJECTED;
  879. }
  880. else
  881. {
  882. pCpCb = GetPointerToCPCB( pPcb, CpIndex );
  883. pCpCb->dwError = ERROR_PPP_CP_REJECTED;
  884. }
  885. RemoveFromTimerQ( pPcb->dwPortId,
  886. pCpCb->LastId,
  887. CpTable[CpIndex].CpInfo.Protocol,
  888. FALSE,
  889. TIMER_EVENT_TIMEOUT );
  890. switch ( pCpCb->State )
  891. {
  892. case FSM_CLOSING:
  893. if ( !FsmThisLayerFinished( pPcb, CpIndex, TRUE ) )
  894. return;
  895. pCpCb->State = FSM_CLOSED;
  896. break;
  897. case FSM_REQ_SENT:
  898. case FSM_ACK_RCVD:
  899. case FSM_ACK_SENT:
  900. case FSM_STOPPING:
  901. if ( !FsmThisLayerFinished( pPcb, CpIndex, TRUE ) )
  902. return;
  903. pCpCb->State = FSM_STOPPED;
  904. break;
  905. case FSM_OPENED:
  906. if ( !FsmThisLayerDown( pPcb, CpIndex ) )
  907. return;
  908. InitRestartCounters( pPcb, pCpCb );
  909. FsmSendTermReq( pPcb, CpIndex );
  910. pCpCb->State = FSM_STOPPING;
  911. break;
  912. case FSM_CLOSED:
  913. case FSM_STOPPED:
  914. break;
  915. case FSM_STARTING:
  916. case FSM_INITIAL:
  917. default:
  918. PPP_ASSERT( pCpCb->State < 10 );
  919. PppLog( 2, "Illegal transition->UnknownCode rcvd while in %s state",
  920. FsmStates[pCpCb->State] );
  921. break;
  922. }
  923. }
  924. //**
  925. //
  926. // Call: NbfCpCompletionRoutine
  927. //
  928. // Returns: none
  929. //
  930. // Description: Called by a NBFCP when it has finished preparing a respose to
  931. // the client's add name request.
  932. //
  933. VOID
  934. NbfCpCompletionRoutine(
  935. IN PCB * pPcb,
  936. IN DWORD CpIndex,
  937. IN CPCB * pCpCb,
  938. IN PPP_CONFIG * pSendConfig
  939. )
  940. {
  941. BOOL fAcked = FALSE;
  942. DWORD dwLength;
  943. DWORD dwRetCode;
  944. switch( pSendConfig->Code )
  945. {
  946. case CONFIG_ACK:
  947. fAcked = TRUE;
  948. break;
  949. case CONFIG_NAK:
  950. if ( pCpCb->NakRetryCount > 0 )
  951. {
  952. (pCpCb->NakRetryCount)--;
  953. }
  954. else
  955. {
  956. pCpCb->dwError = ERROR_PPP_NOT_CONVERGING;
  957. NotifyCallerOfFailure( pPcb, pCpCb->dwError );
  958. return;
  959. }
  960. break;
  961. case CONFIG_REJ:
  962. if ( pCpCb->RejRetryCount > 0 )
  963. {
  964. (pCpCb->RejRetryCount)--;
  965. }
  966. else
  967. {
  968. pCpCb->dwError = ERROR_PPP_NOT_CONVERGING;
  969. FsmClose( pPcb, CpIndex );
  970. return;
  971. }
  972. break;
  973. default:
  974. break;
  975. }
  976. HostToWireFormat16( (WORD)CpTable[CpIndex].CpInfo.Protocol,
  977. (PBYTE)(pPcb->pSendBuf->Protocol) );
  978. dwLength = WireToHostFormat16( pSendConfig->Length );
  979. if ( ( dwLength + PPP_PACKET_HDR_LEN ) > LCP_DEFAULT_MRU )
  980. {
  981. pCpCb->dwError = ERROR_PPP_INVALID_PACKET;
  982. FsmClose( pPcb, CpIndex );
  983. return;
  984. }
  985. else
  986. {
  987. CopyMemory( pPcb->pSendBuf->Information, pSendConfig, dwLength );
  988. }
  989. LogPPPPacket(FALSE,pPcb,pPcb->pSendBuf,dwLength+PPP_PACKET_HDR_LEN);
  990. if ( ( dwRetCode = PortSendOrDisconnect( pPcb,
  991. (dwLength + PPP_PACKET_HDR_LEN)))
  992. != NO_ERROR )
  993. {
  994. return;
  995. }
  996. switch ( pCpCb->State )
  997. {
  998. case FSM_ACK_RCVD:
  999. if ( fAcked )
  1000. {
  1001. pCpCb->State = FSM_OPENED;
  1002. FsmThisLayerUp( pPcb, CpIndex );
  1003. }
  1004. break;
  1005. case FSM_OPENED:
  1006. case FSM_ACK_SENT:
  1007. case FSM_REQ_SENT:
  1008. case FSM_STOPPED:
  1009. pCpCb->State = fAcked ? FSM_ACK_SENT : FSM_REQ_SENT;
  1010. break;
  1011. case FSM_CLOSING:
  1012. case FSM_STOPPING:
  1013. //
  1014. // no transition
  1015. //
  1016. break;
  1017. case FSM_CLOSED:
  1018. case FSM_STARTING:
  1019. case FSM_INITIAL:
  1020. default:
  1021. PPP_ASSERT( pCpCb->State < 10 );
  1022. PppLog( 2, "Illegal transition->ConfigReq rcvd while in %s state",
  1023. FsmStates[pCpCb->State] );
  1024. break;
  1025. }
  1026. }
  1027. //**
  1028. //
  1029. // Call: CompletionRoutine
  1030. //
  1031. // Returns: none
  1032. //
  1033. // Description: Called by a CP when it has completed an asynchronous operation.
  1034. //
  1035. VOID
  1036. CompletionRoutine(
  1037. IN HCONN hPortOrConnection,
  1038. IN DWORD Protocol,
  1039. IN PPP_CONFIG * pSendConfig,
  1040. IN DWORD dwError
  1041. )
  1042. {
  1043. DWORD dwRetCode;
  1044. CPCB * pCpCb;
  1045. PCB * pPcb;
  1046. HPORT hPort;
  1047. DWORD CpIndex = GetCpIndexFromProtocol( Protocol );
  1048. if ( CpIndex == (DWORD)-1 )
  1049. {
  1050. return;
  1051. }
  1052. PppLog( 2, "CompletionRoutine called for protocol %x",
  1053. CpTable[CpIndex].CpInfo.Protocol );
  1054. dwRetCode = RasBundleGetPort( NULL, (HCONN)hPortOrConnection, &hPort );
  1055. if ( dwRetCode != NO_ERROR )
  1056. {
  1057. return;
  1058. }
  1059. pPcb = GetPCBPointerFromhPort( hPort );
  1060. if ( pPcb == (PCB *)NULL )
  1061. {
  1062. return;
  1063. }
  1064. pCpCb = GetPointerToCPCB( pPcb, CpIndex );
  1065. if ( pCpCb == NULL )
  1066. {
  1067. return;
  1068. }
  1069. if ( dwError != NO_ERROR )
  1070. {
  1071. pCpCb->dwError = dwError;
  1072. PppLog( 1,
  1073. "The control protocol for %x on port %d, returned error %d",
  1074. CpTable[CpIndex].CpInfo.Protocol, hPort, dwError );
  1075. FsmClose( pPcb, CpIndex );
  1076. return;
  1077. }
  1078. switch( Protocol )
  1079. {
  1080. case PPP_NBFCP_PROTOCOL:
  1081. NbfCpCompletionRoutine( pPcb, CpIndex, pCpCb, pSendConfig );
  1082. break;
  1083. case PPP_IPXCP_PROTOCOL:
  1084. //
  1085. // If IPXCP is still in the OPENED state then call ThisLayerUp
  1086. // otherwise ignore this call.
  1087. //
  1088. if ( pCpCb->State == FSM_OPENED )
  1089. {
  1090. FsmThisLayerUp( pPcb, CpIndex );
  1091. }
  1092. break;
  1093. default:
  1094. RTASSERT( FALSE );
  1095. break;
  1096. }
  1097. return;
  1098. }
  1099. //**
  1100. //
  1101. // Call: FsmConfigResultReceived
  1102. //
  1103. // Returns: TRUE - Success
  1104. // FALSE - Otherwise
  1105. //
  1106. // Description: This call will process a Config result ie Ack/Nak/Rej.
  1107. //
  1108. BOOL
  1109. FsmConfigResultReceived(
  1110. IN PCB * pPcb,
  1111. IN DWORD CpIndex,
  1112. IN PPP_CONFIG * pRecvConfig
  1113. )
  1114. {
  1115. DWORD dwRetCode;
  1116. CPCB * pCpCb = GetPointerToCPCB( pPcb, CpIndex );
  1117. if ( pCpCb == NULL )
  1118. {
  1119. return( FALSE );
  1120. }
  1121. switch( pRecvConfig->Code )
  1122. {
  1123. case CONFIG_NAK:
  1124. dwRetCode = (CpTable[CpIndex].CpInfo.RasCpConfigNakReceived)(
  1125. pCpCb->pWorkBuf, pRecvConfig );
  1126. break;
  1127. case CONFIG_ACK:
  1128. dwRetCode = (CpTable[CpIndex].CpInfo.RasCpConfigAckReceived)(
  1129. pCpCb->pWorkBuf, pRecvConfig );
  1130. break;
  1131. case CONFIG_REJ:
  1132. dwRetCode = (CpTable[CpIndex].CpInfo.RasCpConfigRejReceived)(
  1133. pCpCb->pWorkBuf, pRecvConfig );
  1134. break;
  1135. default:
  1136. return( FALSE );
  1137. }
  1138. if ( dwRetCode != NO_ERROR )
  1139. {
  1140. if ( dwRetCode == ERROR_PPP_INVALID_PACKET )
  1141. {
  1142. PppLog( 1,
  1143. "Invalid packet received on port %d silently discarded",
  1144. pPcb->hPort );
  1145. }
  1146. else
  1147. {
  1148. PppLog(1,
  1149. "The control protocol for %x on port %d returned error %d",
  1150. CpTable[CpIndex].CpInfo.Protocol, pPcb->hPort, dwRetCode );
  1151. if ( CpTable[CpIndex].CpInfo.Protocol == PPP_CCP_PROTOCOL )
  1152. {
  1153. //
  1154. // If we need to force encryption but encryption negotiation
  1155. // failed then we drop the link
  1156. //
  1157. if ( pPcb->ConfigInfo.dwConfigMask &
  1158. (PPPCFG_RequireEncryption |
  1159. PPPCFG_RequireStrongEncryption ) )
  1160. {
  1161. PppLog( 1, "Encryption is required" );
  1162. switch( dwRetCode )
  1163. {
  1164. case ERROR_NO_LOCAL_ENCRYPTION:
  1165. case ERROR_NO_REMOTE_ENCRYPTION:
  1166. pPcb->LcpCb.dwError = dwRetCode;
  1167. break;
  1168. case ERROR_PROTOCOL_NOT_CONFIGURED:
  1169. pPcb->LcpCb.dwError = ERROR_NO_LOCAL_ENCRYPTION;
  1170. break;
  1171. default:
  1172. pPcb->LcpCb.dwError = ERROR_NO_REMOTE_ENCRYPTION;
  1173. break;
  1174. }
  1175. //
  1176. // We need to send an Accounting Stop if RADIUS sends
  1177. // an Access Accept but we still drop the line.
  1178. //
  1179. pPcb->fFlags |= PCBFLAG_SERVICE_UNAVAILABLE;
  1180. //
  1181. // If we do FsmClose for CCP instead, the other side may
  1182. // conclude that PPP was negotiated successfully before we
  1183. // send an LCP Terminate Request.
  1184. //
  1185. FsmClose( pPcb, LCP_INDEX );
  1186. return( FALSE );
  1187. }
  1188. }
  1189. pCpCb->dwError = dwRetCode;
  1190. FsmClose( pPcb, CpIndex );
  1191. }
  1192. return( FALSE );
  1193. }
  1194. return( TRUE );
  1195. }
  1196. //**
  1197. //
  1198. // Call: ReceiveIdentification
  1199. //
  1200. // Returns: none
  1201. //
  1202. // Description: Handles an incomming IDENTIFICATION packet.
  1203. //
  1204. VOID
  1205. ReceiveIdentification(
  1206. IN PCB * pPcb,
  1207. IN DWORD CpIndex,
  1208. IN CPCB * pCpCb,
  1209. IN PPP_CONFIG * pRecvConfig
  1210. )
  1211. {
  1212. DWORD dwLength = WireToHostFormat16( pRecvConfig->Length );
  1213. RAS_AUTH_ATTRIBUTE * pAttributes = pPcb->pUserAttributes;
  1214. BYTE MSRASClient[MAX_COMPUTERNAME_LENGTH
  1215. + sizeof(MS_RAS_WITH_MESSENGER) + 10];
  1216. PBYTE pbTempBuf = NULL;
  1217. BYTE MSRASClientVersion[30];
  1218. DWORD dwIndex = 0;
  1219. DWORD dwRetCode = NO_ERROR;
  1220. PppLog( 2, "Identification packet received" );
  1221. //
  1222. // If we are a client we just discard this packet.
  1223. //
  1224. if ( !(pPcb->fFlags & PCBFLAG_IS_SERVER) )
  1225. {
  1226. return;
  1227. }
  1228. //
  1229. // check to see if the identification is version.
  1230. // if version store it in version field
  1231. // or else store it in computer name field
  1232. //
  1233. // If this is not our identification message
  1234. //
  1235. if ( (dwLength < PPP_CONFIG_HDR_LEN+4+strlen(MS_RAS_WITH_MESSENGER)) ||
  1236. (dwLength > PPP_CONFIG_HDR_LEN+4+
  1237. strlen(MS_RAS_WITH_MESSENGER)+MAX_COMPUTERNAME_LENGTH))
  1238. {
  1239. *(pPcb->pBcb->szComputerName) = (CHAR)NULL;
  1240. *(pPcb->pBcb->szClientVersion) = (CHAR)NULL;
  1241. return;
  1242. }
  1243. for (dwIndex = 0;
  1244. pAttributes[dwIndex].raaType != raatMinimum;
  1245. dwIndex ++);
  1246. //
  1247. // If theres no space in the user attributes list
  1248. // expand the list for the one new attribute being
  1249. // added.
  1250. //
  1251. if(dwIndex >= PPP_NUM_USER_ATTRIBUTES)
  1252. {
  1253. pAttributes = RasAuthAttributeCopyWithAlloc(
  1254. pPcb->pUserAttributes, 1);
  1255. PppLog(1, "ReceiveIdentification: allocated new user list %p",
  1256. pAttributes);
  1257. if(NULL == pAttributes)
  1258. {
  1259. PppLog(1, "ReceiveIdentification: Failed to allocate attributes. %d",
  1260. GetLastError());
  1261. return;
  1262. }
  1263. }
  1264. //
  1265. // Convert the ppp message into a string
  1266. //
  1267. pbTempBuf = LocalAlloc(LPTR, dwLength );
  1268. if ( NULL == pbTempBuf )
  1269. {
  1270. PppLog( 1,
  1271. "ReceiveIdentification: Failed to alloc memory %d",
  1272. GetLastError()
  1273. );
  1274. }
  1275. memcpy ( pbTempBuf,
  1276. pRecvConfig->Data+4,
  1277. dwLength - PPP_CONFIG_HDR_LEN - 4
  1278. );
  1279. //
  1280. // And add the attribs to the list of User Attributes
  1281. //
  1282. if ( strstr ( pbTempBuf, MS_RAS_WITHOUT_MESSENGER ) ||
  1283. strstr ( pbTempBuf, MS_RAS_WITH_MESSENGER )
  1284. )
  1285. {
  1286. //
  1287. // computer name
  1288. //
  1289. ZeroMemory( pPcb->pBcb->szComputerName,
  1290. sizeof(pPcb->pBcb->szComputerName));
  1291. CopyMemory( pPcb->pBcb->szComputerName,
  1292. pbTempBuf,
  1293. dwLength - PPP_CONFIG_HDR_LEN - 4 );
  1294. //
  1295. // Vendor-Id
  1296. //
  1297. HostToWireFormat32( 311, MSRASClient );
  1298. //
  1299. // Vendor-Type: MS-RAS-Client - New
  1300. //
  1301. MSRASClient[4] = 34;
  1302. //
  1303. // Length
  1304. //
  1305. MSRASClient[5] = 2 + (BYTE) (dwLength - PPP_CONFIG_HDR_LEN - 4);
  1306. //
  1307. // Vendor-Id
  1308. //
  1309. CopyMemory ( MSRASClient + 6,
  1310. pPcb->pBcb->szComputerName,
  1311. dwLength - PPP_CONFIG_HDR_LEN - 4) ;
  1312. pAttributes[dwIndex].raaType = raatReserved;
  1313. dwRetCode = RasAuthAttributeInsert( dwIndex++,
  1314. pAttributes,
  1315. raatVendorSpecific,
  1316. FALSE,
  1317. 6 + dwLength - PPP_CONFIG_HDR_LEN - 4,
  1318. &MSRASClient );
  1319. if ( NO_ERROR != dwRetCode )
  1320. {
  1321. PppLog( 2, "Error inserting user attribute = %s, %d",
  1322. pPcb->pBcb->szComputerName, dwRetCode );
  1323. }
  1324. PppLog(2, "Remote identification = %s", pPcb->pBcb->szComputerName);
  1325. }
  1326. else
  1327. {
  1328. //
  1329. // version
  1330. //
  1331. ZeroMemory( pPcb->pBcb->szClientVersion,
  1332. sizeof( pPcb->pBcb->szClientVersion ) );
  1333. CopyMemory( pPcb->pBcb->szClientVersion,
  1334. pRecvConfig->Data+4,
  1335. dwLength - PPP_CONFIG_HDR_LEN - 4 );
  1336. //
  1337. // Vendor-Id
  1338. //
  1339. HostToWireFormat32( 311, MSRASClientVersion );
  1340. //
  1341. // Vendor-Type: MS-RAS-Client-Version
  1342. //
  1343. MSRASClientVersion[4] = 35;
  1344. //
  1345. // Vendor-Length
  1346. //
  1347. MSRASClientVersion[5] = (BYTE)(2 + dwLength - PPP_CONFIG_HDR_LEN - 4);
  1348. CopyMemory( MSRASClientVersion + 6,
  1349. pPcb->pBcb->szClientVersion,
  1350. dwLength - PPP_CONFIG_HDR_LEN - 4 );
  1351. pAttributes[dwIndex].raaType = raatReserved;
  1352. dwRetCode = RasAuthAttributeInsert( dwIndex++,
  1353. pAttributes,
  1354. raatVendorSpecific,
  1355. FALSE,
  1356. 6 + dwLength - PPP_CONFIG_HDR_LEN - 4,
  1357. &MSRASClientVersion );
  1358. if ( dwRetCode != NO_ERROR )
  1359. {
  1360. PppLog( 2, "Error inserting user attribute = %s, %d", pPcb->pBcb->szClientVersion, dwRetCode );
  1361. }
  1362. PppLog( 2, "Remote identification = %s", pPcb->pBcb->szClientVersion );
  1363. }
  1364. pAttributes[dwIndex].raaType = raatMinimum;
  1365. pAttributes[dwIndex].dwLength = 0;
  1366. pAttributes[dwIndex].Value = NULL;
  1367. //
  1368. // If we allocated a new attribute list, free the old list and save
  1369. // the new one.
  1370. //
  1371. if(pPcb->pUserAttributes != pAttributes)
  1372. {
  1373. PppLog(2, "ReceiveIdentification: Replaced userlist %p with %p",
  1374. pPcb->pUserAttributes,
  1375. pAttributes);
  1376. RasAuthAttributeDestroy(pPcb->pUserAttributes);
  1377. pPcb->pUserAttributes = pAttributes;
  1378. }
  1379. if ( pbTempBuf )
  1380. LocalFree(pbTempBuf);
  1381. return;
  1382. }
  1383. //**
  1384. //
  1385. // Call: ReceiveTimeRemaining
  1386. //
  1387. // Returns: none
  1388. //
  1389. // Description: Handles an incomming TIME_REMAINING packet.
  1390. //
  1391. VOID
  1392. ReceiveTimeRemaining(
  1393. IN PCB * pPcb,
  1394. IN DWORD CpIndex,
  1395. IN CPCB * pCpCb,
  1396. IN PPP_CONFIG * pRecvConfig
  1397. )
  1398. {
  1399. DWORD dwLength = WireToHostFormat16( pRecvConfig->Length );
  1400. PppLog( 2, "Time Remaining packet received");
  1401. //
  1402. // If we are a server we just discard this packet.
  1403. //
  1404. if ( pPcb->fFlags & PCBFLAG_IS_SERVER )
  1405. {
  1406. return;
  1407. }
  1408. //
  1409. // If this is not our time remaining message
  1410. //
  1411. if ( dwLength != PPP_CONFIG_HDR_LEN + 8 + strlen( MS_RAS ) )
  1412. {
  1413. return;
  1414. }
  1415. return;
  1416. }