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.

700 lines
16 KiB

  1. /********************************************************************/
  2. /** Copyright(c) 1998 Microsoft Corporation. **/
  3. /********************************************************************/
  4. //***
  5. //
  6. // Filename: exports.c
  7. //
  8. // Description: Contains routines that are exported to the PPP engine. The
  9. // engine calls into these routines for ATCP connections
  10. //
  11. // History: Feb 26, 1998 Shirish Koti Created original version.
  12. //
  13. //***
  14. #include <nt.h>
  15. #include <ntrtl.h>
  16. #include <nturtl.h>
  17. #include <windows.h>
  18. #include <lmcons.h>
  19. #include <string.h>
  20. #include <stdlib.h>
  21. #include <llinfo.h>
  22. #include <rasman.h>
  23. #include <rtutils.h>
  24. #include <devioctl.h>
  25. #include <rasppp.h>
  26. #include <pppcp.h>
  27. #define INCL_HOSTWIRE
  28. #include <ppputil.h>
  29. #include <raserror.h>
  30. #include <arapio.h>
  31. #include "rasatcp.h"
  32. //***
  33. //
  34. // Function: AtcpGetInfo
  35. // PPP engine calls this routine to get entry points into ATCP
  36. //
  37. // Parameters: dwProtocolId - unused here!
  38. // pInfo - info that we fill out and pass back to PPP engine
  39. //
  40. // Return: NO_ERROR
  41. //
  42. //***$
  43. DWORD
  44. AtcpGetInfo(
  45. IN DWORD dwProtocolId,
  46. OUT PPPCP_INFO *pInfo
  47. )
  48. {
  49. ZeroMemory( pInfo, sizeof(PPPCP_INFO) );
  50. pInfo->Protocol = (DWORD )PPP_ATCP_PROTOCOL;
  51. lstrcpy(pInfo->SzProtocolName, "Atcp");
  52. pInfo->Recognize = 7;
  53. pInfo->RasCpInit = AtcpInit;
  54. pInfo->RasCpBegin = AtcpBegin;
  55. pInfo->RasCpReset = AtcpReset;
  56. pInfo->RasCpEnd = AtcpEnd;
  57. pInfo->RasCpThisLayerUp = AtcpThisLayerUp;
  58. pInfo->RasCpMakeConfigRequest = AtcpMakeConfigRequest;
  59. pInfo->RasCpMakeConfigResult = AtcpMakeConfigResult;
  60. pInfo->RasCpConfigAckReceived = AtcpConfigAckReceived;
  61. pInfo->RasCpConfigNakReceived = AtcpConfigNakReceived;
  62. pInfo->RasCpConfigRejReceived = AtcpConfigRejReceived;
  63. pInfo->RasCpGetNegotiatedInfo = AtcpGetNegotiatedInfo;
  64. pInfo->RasCpProjectionNotification = AtcpProjectionNotification;
  65. return 0;
  66. }
  67. //***
  68. //
  69. // Function: AtcpInit
  70. // PPP engine calls this routine to initialize ATCP
  71. //
  72. // Parameters: fInitialize - TRUE to initialize, FALSE to de-initialize
  73. //
  74. // Return: NO_ERROR if things go fine
  75. // Errorcode if something fails
  76. //
  77. //***$
  78. DWORD
  79. AtcpInit(
  80. IN BOOL fInitialize
  81. )
  82. {
  83. DWORD dwRetCode=NO_ERROR;
  84. if (fInitialize)
  85. {
  86. // open handle to appletalk stack
  87. if (!AtcpHandle)
  88. {
  89. atcpOpenHandle();
  90. }
  91. dwRetCode = atcpStartup();
  92. }
  93. else
  94. {
  95. // if we had a handle open to appletalk stack, close it
  96. if (AtcpHandle)
  97. {
  98. atcpCloseHandle();
  99. }
  100. dwRetCode = atcpShutdown();
  101. }
  102. return(dwRetCode);
  103. }
  104. //***
  105. //
  106. // Function: AtcpBegin
  107. // PPP engine calls this routine to mark starting of a connection
  108. // setup.
  109. //
  110. // Parameters: ppContext - context that we pass back
  111. // pInfo - PPPCP_INIT info
  112. //
  113. // Return: result of the operation
  114. //
  115. //***$
  116. DWORD
  117. AtcpBegin(
  118. OUT PVOID *ppContext,
  119. IN PVOID pInfo
  120. )
  121. {
  122. DWORD dwRetCode;
  123. PATCPCONN pAtcpConn=NULL;
  124. *ppContext = NULL;
  125. // open handle to stack if not already done so
  126. if (!AtcpHandle)
  127. {
  128. atcpOpenHandle();
  129. }
  130. if (AtcpHandle == NULL)
  131. {
  132. ATCP_DBGPRINT(("atcpAtkSetup: AtcpHandle is NULL!\n"));
  133. return(ARAPERR_IOCTL_FAILURE);
  134. }
  135. //
  136. // allocate, initialize our connection context
  137. //
  138. if ((pAtcpConn = atcpAllocConnection((PPPCP_INIT *)pInfo)) == NULL)
  139. {
  140. ATCP_DBGPRINT(("AtcpBegin: malloc failed\n"));
  141. return(ERROR_NOT_ENOUGH_MEMORY);
  142. }
  143. //
  144. // tell stack to allocate a context for this connection. Also, reserve a
  145. // network addr for this client and get zone, router info
  146. //
  147. dwRetCode = atcpAtkSetup(pAtcpConn, IOCTL_ATCP_SETUP_CONNECTION);
  148. if (dwRetCode != NO_ERROR)
  149. {
  150. ATCP_DBGPRINT(("AtcpBegin: atcpAtkSetup failed %lx\n",dwRetCode));
  151. LocalFree(pAtcpConn);
  152. return(dwRetCode);
  153. }
  154. ATCP_DBGPRINT(("AtcpBegin: client's network addr %x.%x (%lx)\n",
  155. pAtcpConn->ClientAddr.ata_Network,pAtcpConn->ClientAddr.ata_Node,pAtcpConn));
  156. //
  157. // allocate Route so we can call RasActivateRoute later...
  158. //
  159. dwRetCode = RasAllocateRoute(
  160. pAtcpConn->hPort,
  161. APPLETALK,
  162. TRUE,
  163. &pAtcpConn->RouteInfo);
  164. if (dwRetCode != NO_ERROR)
  165. {
  166. ATCP_DBGPRINT(("AtcpBegin: RasAllocateRoute failed %lx\n",dwRetCode));
  167. // tell the stack to close the connection
  168. atcpCloseAtalkConnection(pAtcpConn);
  169. LocalFree(pAtcpConn);
  170. return(dwRetCode);
  171. }
  172. *ppContext = (PVOID)pAtcpConn;
  173. return 0;
  174. }
  175. //***
  176. //
  177. // Function: AtcpThisLayerUp
  178. // PPP engine calls this routine to tell us ATCP setup is done
  179. //
  180. // Parameters: pContext - our context
  181. //
  182. // Return: result of the operation
  183. //
  184. //***$
  185. DWORD
  186. AtcpThisLayerUp(
  187. IN PVOID pContext
  188. )
  189. {
  190. PATCPCONN pAtcpConn;
  191. BYTE ConfigInfo[ARAP_BIND_SIZE];
  192. PROTOCOL_CONFIG_INFO *pCfgInfo;
  193. PARAP_BIND_INFO pBindInfo;
  194. DWORD dwRetCode;
  195. pAtcpConn = (PATCPCONN)pContext;
  196. ATCP_ASSERT(pAtcpConn->Signature == ATCP_SIGNATURE);
  197. EnterCriticalSection(&pAtcpConn->CritSect);
  198. if (pAtcpConn->fLineUpDone)
  199. {
  200. ATCP_DBGPRINT(("AtcpThisLayerUp: LineUp already done\n"));
  201. LeaveCriticalSection(&pAtcpConn->CritSect);
  202. return(NO_ERROR);
  203. }
  204. pAtcpConn->fLineUpDone = TRUE;
  205. LeaveCriticalSection(&pAtcpConn->CritSect);
  206. if (pAtcpConn->SuppressRtmp || pAtcpConn->SuppressAllBcast)
  207. {
  208. atcpAtkSetup(pAtcpConn, IOCTL_ATCP_SUPPRESS_BCAST);
  209. }
  210. pCfgInfo = (PROTOCOL_CONFIG_INFO *)ConfigInfo;
  211. pBindInfo = (PARAP_BIND_INFO)&pCfgInfo->P_Info[0];
  212. pCfgInfo->P_Length = ARAP_BIND_SIZE;
  213. //
  214. // plumb our protocol-specific info
  215. //
  216. pBindInfo->BufLen = sizeof( ARAP_BIND_INFO );
  217. pBindInfo->pDllContext = pAtcpConn;
  218. pBindInfo->fThisIsPPP = TRUE;
  219. pBindInfo->ClientAddr = pAtcpConn->ClientAddr;
  220. pBindInfo->AtalkContext = pAtcpConn->AtalkContext;
  221. pBindInfo->ErrorCode = (DWORD)-1;
  222. //
  223. // pass it down to ndiswan so our stack gets a line-up!
  224. //
  225. dwRetCode = RasActivateRoute(
  226. pAtcpConn->hPort,
  227. APPLETALK,
  228. &pAtcpConn->RouteInfo,
  229. pCfgInfo);
  230. if (dwRetCode != NO_ERROR)
  231. {
  232. ATCP_DBGPRINT(("AtcpProjectionNotification: RasActivateRoute failed %lx\n",
  233. dwRetCode));
  234. return(dwRetCode);
  235. }
  236. ATCP_DBGPRINT(("AtcpThisLayerUp: LineUp done on %lx\n",pAtcpConn));
  237. return 0;
  238. }
  239. //***
  240. //
  241. // Function: AtcpMakeConfigRequest
  242. // PPP engine calls this routine to ask us to prepare an
  243. // ATCP ConfigRequest packet
  244. //
  245. // Parameters: pContext - our context
  246. // pSendBuf - PPP_CONFIG info for this request
  247. // cbSendBuf - how big is the Data buffer
  248. //
  249. // Return: result of the operation
  250. //
  251. //***$
  252. DWORD
  253. AtcpMakeConfigRequest(
  254. IN PVOID pContext,
  255. OUT PPP_CONFIG *pSendBuf,
  256. IN DWORD cbSendBuf
  257. )
  258. {
  259. PATCPCONN pAtcpConn;
  260. DWORD dwRetCode;
  261. USHORT OptionType;
  262. BOOL fConfigDone=FALSE;
  263. BYTE ParseResult[ATCP_OPT_MAX_VAL];
  264. pAtcpConn = (PATCPCONN)pContext;
  265. ATCP_ASSERT(pAtcpConn->Signature == ATCP_SIGNATURE);
  266. EnterCriticalSection(&pAtcpConn->CritSect);
  267. if (pAtcpConn->Flags & ATCP_CONFIG_REQ_DONE)
  268. {
  269. fConfigDone = TRUE;
  270. }
  271. LeaveCriticalSection(&pAtcpConn->CritSect);
  272. if (fConfigDone)
  273. {
  274. pSendBuf->Code = CONFIG_REQ;
  275. HostToWireFormat16(4, pSendBuf->Length );
  276. ATCP_DBGPRINT(("AtcpMakeConfigRequest: our-side config done, returning\n"));
  277. return(NO_ERROR);
  278. }
  279. // initialize everything to not-needed
  280. for (OptionType=1; OptionType<ATCP_OPT_MAX_VAL; OptionType++ )
  281. {
  282. ParseResult[OptionType] = ATCP_NOT_REQUESTED;
  283. }
  284. // set the ones we want
  285. ParseResult[ATCP_OPT_APPLETALK_ADDRESS] = ATCP_REQ;
  286. ParseResult[ATCP_OPT_SERVER_INFORMATION] = ATCP_REQ;
  287. ParseResult[ATCP_OPT_ZONE_INFORMATION] = ATCP_REQ;
  288. ParseResult[ATCP_OPT_DEFAULT_ROUTER_ADDRESS] = ATCP_REQ;
  289. // prepare our ConfigRequest
  290. dwRetCode = atcpPrepareResponse(
  291. pAtcpConn,
  292. pSendBuf,
  293. cbSendBuf,
  294. ParseResult);
  295. if (dwRetCode != NO_ERROR)
  296. {
  297. ATCP_DBGPRINT(("AtcpMakeConfigRequest: atcpPrepareResponse failed %lx\n",
  298. dwRetCode));
  299. return(dwRetCode);
  300. }
  301. return(NO_ERROR);
  302. }
  303. //***
  304. //
  305. // Function: AtcpMakeConfigResult
  306. // PPP engine calls this routine to ask us to prepare a response:
  307. // ConfigAck, ConfigNak or ConfigReject
  308. //
  309. // Parameters: pContext - our context
  310. // pReceiveBuf - PPP_CONFIG info: the request
  311. // pSendBuf - PPP_CONFIG info: our response
  312. // cbSendBuf - how big is the Data buffer for our response
  313. // fRejectNaks - if TRUE, Reject an option instead of Nak'ing it
  314. //
  315. // Return: result of the operation
  316. //
  317. //***$
  318. DWORD
  319. AtcpMakeConfigResult(
  320. IN PVOID pContext,
  321. IN PPP_CONFIG *pReceiveBuf,
  322. OUT PPP_CONFIG *pSendBuf,
  323. IN DWORD cbSendBuf,
  324. IN BOOL fRejectNaks
  325. )
  326. {
  327. PATCPCONN pAtcpConn;
  328. DWORD dwRetCode;
  329. BYTE ParseResult[ATCP_OPT_MAX_VAL+1];
  330. BOOL fRejectingSomething=FALSE;
  331. pAtcpConn = (PATCPCONN)pContext;
  332. ATCP_ASSERT(pAtcpConn->Signature == ATCP_SIGNATURE);
  333. //
  334. // parse this request.
  335. //
  336. dwRetCode = atcpParseRequest(
  337. pAtcpConn,
  338. pReceiveBuf,
  339. pSendBuf,
  340. cbSendBuf,
  341. ParseResult,
  342. &fRejectingSomething);
  343. if (dwRetCode != NO_ERROR)
  344. {
  345. ATCP_DBGPRINT(("AtcpMakeConfigResult: atcpParseRequest failed %lx\n",
  346. dwRetCode));
  347. return(dwRetCode);
  348. }
  349. //
  350. // If some option needs to be rejected, the outgoing buffer already
  351. // contains the appropriate stuff: just return here
  352. //
  353. if (fRejectingSomething)
  354. {
  355. return(NO_ERROR);
  356. }
  357. //
  358. // we are not rejecting any option. Prepare a response buffer to send
  359. //
  360. dwRetCode = atcpPrepareResponse(
  361. pAtcpConn,
  362. pSendBuf,
  363. cbSendBuf,
  364. ParseResult);
  365. if (dwRetCode != NO_ERROR)
  366. {
  367. ATCP_DBGPRINT(("AtcpMakeConfigResult: atcpPrepareResponse failed %lx\n",
  368. dwRetCode));
  369. return(dwRetCode);
  370. }
  371. return(NO_ERROR);
  372. }
  373. //***
  374. //
  375. // Function: AtcpConfigAckReceived
  376. // PPP engine calls this routine to tell us that we got ConfigAck
  377. //
  378. // Parameters: pContext - our context
  379. // pReceiveBuf - PPP_CONFIG info: the ack
  380. //
  381. // Return: result of the operation
  382. //
  383. //***$
  384. DWORD
  385. AtcpConfigAckReceived(
  386. IN PVOID pContext,
  387. IN PPP_CONFIG *pReceiveBuf
  388. )
  389. {
  390. PATCPCONN pAtcpConn;
  391. pAtcpConn = (PATCPCONN)pContext;
  392. ATCP_ASSERT(pAtcpConn->Signature == ATCP_SIGNATURE);
  393. // client is happy with our-side configuration
  394. EnterCriticalSection(&pAtcpConn->CritSect);
  395. pAtcpConn->Flags |= ATCP_CONFIG_REQ_DONE;
  396. LeaveCriticalSection(&pAtcpConn->CritSect);
  397. return 0;
  398. }
  399. //***
  400. //
  401. // Function: AtcpConfigNakReceived
  402. // PPP engine calls this routine to tell us that we got ConfigNak
  403. //
  404. // Parameters: pContext - our context
  405. // pReceiveBuf - PPP_CONFIG info: the ack
  406. //
  407. // Return: result of the operation
  408. //
  409. //***$
  410. DWORD
  411. AtcpConfigNakReceived(
  412. IN PVOID pContext,
  413. IN PPP_CONFIG *pReceiveBuf
  414. )
  415. {
  416. PATCPCONN pAtcpConn;
  417. ATCP_DBGPRINT(("AtcpConfigNakReceived entered\n"));
  418. pAtcpConn = (PATCPCONN)pContext;
  419. ATCP_ASSERT(pAtcpConn->Signature == ATCP_SIGNATURE);
  420. ATCP_DUMP_BYTES("AtcpConfigNakReceived: Nak received from client",
  421. &pReceiveBuf->Data[0],
  422. (DWORD)WireToHostFormat16( pReceiveBuf->Length ) - 4);
  423. return 0;
  424. }
  425. //***
  426. //
  427. // Function: AtcpConfigRejReceived
  428. // PPP engine calls this routine to tell us that we got ConfigRej
  429. //
  430. // Parameters: pContext - our context
  431. // pReceiveBuf - PPP_CONFIG info: the ack
  432. //
  433. // Return: result of the operation
  434. //
  435. //***$
  436. DWORD
  437. AtcpConfigRejReceived(
  438. IN PVOID pContext,
  439. IN PPP_CONFIG *pReceiveBuf
  440. )
  441. {
  442. PATCPCONN pAtcpConn;
  443. ATCP_DBGPRINT(("AtcpConfigRejReceived entered\n"));
  444. pAtcpConn = (PATCPCONN)pContext;
  445. ATCP_ASSERT(pAtcpConn->Signature == ATCP_SIGNATURE);
  446. return 0;
  447. }
  448. //***
  449. //
  450. // Function: AtcpGetNegotiatedInfo
  451. // PPP engine calls this routine to retrieve from us the info that
  452. // finally got negotiated.
  453. //
  454. // Parameters: pContext - our context
  455. // pReceiveBuf - PPP_CONFIG info: the ack
  456. //
  457. // Return: result of the operation
  458. //
  459. //***$
  460. DWORD
  461. AtcpGetNegotiatedInfo(
  462. IN PVOID pContext,
  463. OUT PPP_ATCP_RESULT *pAtcpResult
  464. )
  465. {
  466. PATCPCONN pAtcpConn;
  467. pAtcpConn = (PATCPCONN)pContext;
  468. ATCP_ASSERT(pAtcpConn->Signature == ATCP_SIGNATURE);
  469. pAtcpResult->dwError = 0;
  470. pAtcpResult->dwLocalAddress = *(DWORD *)&AtcpServerAddress;
  471. pAtcpResult->dwRemoteAddress = *(DWORD *)&pAtcpConn->ClientAddr;
  472. return 0;
  473. }
  474. //***
  475. //
  476. // Function: AtcpProjectionNotification
  477. // PPP engine calls this routine to tell us that all CPs have been
  478. // negotiated.
  479. //
  480. // Parameters: pContext - our context
  481. // pProjectionResult - PPP_PROJECTION_RESULT info
  482. //
  483. // Return: result of the operation
  484. //
  485. //***$
  486. DWORD
  487. AtcpProjectionNotification(
  488. IN PVOID pContext,
  489. IN PVOID pProjectionResult
  490. )
  491. {
  492. PATCPCONN pAtcpConn;
  493. ATCP_DBGPRINT(("AtcpProjectionNotification entered\n"));
  494. pAtcpConn = (PATCPCONN)pContext;
  495. ATCP_ASSERT(pAtcpConn->Signature == ATCP_SIGNATURE);
  496. return 0;
  497. }
  498. //***
  499. //
  500. // Function: AtcpReset
  501. // Don't know when/why PPP engine calls this routine: this routine
  502. // just returns success!
  503. //
  504. // Parameters: pContext - our context
  505. //
  506. // Return: always 0
  507. //
  508. //***$
  509. DWORD
  510. AtcpReset(
  511. IN PVOID pContext
  512. )
  513. {
  514. PATCPCONN pAtcpConn;
  515. ATCP_DBGPRINT(("AtcpReset entered\n"));
  516. pAtcpConn = (PATCPCONN)pContext;
  517. ATCP_ASSERT(pAtcpConn->Signature == ATCP_SIGNATURE);
  518. return 0;
  519. }
  520. //***
  521. //
  522. // Function: AtcpEnd
  523. // PPP engine calls this routine to mark end of a connection.
  524. //
  525. // Parameters: pContext - our context
  526. //
  527. // Return: result of the operation
  528. //
  529. //***$
  530. DWORD
  531. AtcpEnd(
  532. IN PVOID pContext
  533. )
  534. {
  535. PATCPCONN pAtcpConn;
  536. ATCP_DBGPRINT(("AtcpEnd entered\n"));
  537. pAtcpConn = (PATCPCONN)pContext;
  538. ATCP_ASSERT(pAtcpConn->Signature == ATCP_SIGNATURE);
  539. // tell the stack to close the connection
  540. atcpCloseAtalkConnection(pAtcpConn);
  541. // deactivate the ras route so stack gets a line-down
  542. RasDeAllocateRoute(pAtcpConn->hConnection, APPLETALK);
  543. if (pAtcpConn->fCritSectInitialized)
  544. {
  545. DeleteCriticalSection( &pAtcpConn->CritSect );
  546. pAtcpConn->fCritSectInitialized = FALSE;
  547. }
  548. #if DBG
  549. // mess up the memory so we can catch bad things (using free'd memory etc.)
  550. memset( pAtcpConn, 'f', sizeof(ATCPCONN) );
  551. pAtcpConn->Signature = 0xDEADBEEF;
  552. #endif
  553. LocalFree(pAtcpConn);
  554. EnterCriticalSection( &AtcpCritSect );
  555. AtcpNumConnections--;
  556. LeaveCriticalSection( &AtcpCritSect );
  557. return 0;
  558. }