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.

1049 lines
28 KiB

  1. /********************************************************************/
  2. /** Copyright(c) 1998 Microsoft Corporation. **/
  3. /********************************************************************/
  4. //***
  5. //
  6. // Filename: rasatcp.c
  7. //
  8. // Description: Contains routines that implement the ATCP functionality.
  9. //
  10. // History: Feb 26, 1998 Shirish Koti Created original version.
  11. //
  12. //***
  13. #include <nt.h>
  14. #include <ntrtl.h>
  15. #include <nturtl.h>
  16. #include <windows.h>
  17. #include <lmcons.h>
  18. #include <string.h>
  19. #include <stdlib.h>
  20. #include <llinfo.h>
  21. #include <rasman.h>
  22. #include <rtutils.h>
  23. #include <devioctl.h>
  24. #include <rasppp.h>
  25. #include <pppcp.h>
  26. #define INCL_HOSTWIRE
  27. #include <ppputil.h>
  28. #include <raserror.h>
  29. #include <arapio.h>
  30. #include "rasatcp.h"
  31. //
  32. // Globals
  33. //
  34. HANDLE AtcpHandle=NULL;
  35. CRITICAL_SECTION AtcpCritSect;
  36. NET_ADDR AtcpServerAddress;
  37. NET_ADDR AtcpDefaultRouter;
  38. DWORD AtcpNumConnections=0;
  39. UCHAR AtcpServerName[NAMESTR_LEN];
  40. UCHAR AtcpZoneName[ZONESTR_LEN];
  41. //***
  42. //
  43. // Function: atcpStartup
  44. // This routine does init time setup
  45. //
  46. // Return: result of operation
  47. //
  48. //***$
  49. DWORD
  50. atcpStartup(
  51. IN VOID
  52. )
  53. {
  54. DWORD dwRetCode=NO_ERROR;
  55. DWORD dwSrvNameLen=MAX_COMPUTERNAME_LENGTH+1;
  56. // get the server name
  57. if (!GetComputerName((LPTSTR)&AtcpServerName[1],&dwSrvNameLen))
  58. {
  59. dwRetCode = GetLastError();
  60. ATCP_DBGPRINT(("atcpStartup: GetComputerName failed %ld\n",dwRetCode));
  61. return(dwRetCode);
  62. }
  63. // store it in Pascal string format
  64. AtcpServerName[0] = (BYTE)dwSrvNameLen;
  65. InitializeCriticalSection( &AtcpCritSect );
  66. return(dwRetCode);
  67. }
  68. //***
  69. //
  70. // Function: atcpOpenHandle
  71. // Opens the RAS device exported by the appletalk stack
  72. //
  73. // Parameters: None
  74. //
  75. // Return: None
  76. //
  77. // Globals: AtcpHandle, if successful
  78. //
  79. //***$
  80. VOID
  81. atcpOpenHandle(
  82. IN VOID
  83. )
  84. {
  85. NTSTATUS status;
  86. OBJECT_ATTRIBUTES ObjectAttributes;
  87. UNICODE_STRING DeviceName;
  88. IO_STATUS_BLOCK IoStatus;
  89. HANDLE hLocalHandle;
  90. if (AtcpHandle)
  91. {
  92. ATCP_DBGPRINT(("atcpOpenHandle: handle %lx already open!\n",AtcpHandle));
  93. return;
  94. }
  95. RtlInitUnicodeString( &DeviceName, ARAP_DEVICE_NAME );
  96. InitializeObjectAttributes(
  97. &ObjectAttributes,
  98. &DeviceName,
  99. OBJ_CASE_INSENSITIVE,
  100. NULL,
  101. NULL );
  102. status = NtCreateFile(
  103. &hLocalHandle,
  104. SYNCHRONIZE | FILE_READ_DATA | FILE_WRITE_DATA,
  105. &ObjectAttributes,
  106. &IoStatus,
  107. NULL,
  108. FILE_ATTRIBUTE_NORMAL,
  109. FILE_SHARE_READ | FILE_SHARE_WRITE,
  110. FILE_OPEN_IF,
  111. 0,
  112. NULL,
  113. 0 );
  114. if ( NT_SUCCESS(status) )
  115. {
  116. AtcpHandle = hLocalHandle;
  117. ATCP_DBGPRINT(("atcpOpenHandle: NtCreateFile succeeded\n",status));
  118. }
  119. else
  120. {
  121. ATCP_DBGPRINT(("atcpOpenHandle: NtCreateFile failed %lx\n",status));
  122. }
  123. }
  124. //***
  125. //
  126. // Function: atcpCloseHandle
  127. // Closes the RAS device (opened in atcpOpenHandle)
  128. //
  129. // Parameters: None
  130. //
  131. // Return: None
  132. //
  133. // Globals: AtalkHandle
  134. //
  135. //***$
  136. VOID
  137. atcpCloseHandle(
  138. IN VOID
  139. )
  140. {
  141. NTSTATUS status=STATUS_SUCCESS;
  142. if (!AtcpHandle)
  143. {
  144. ATCP_DBGPRINT(("atcpCloseHandle: handle already closed!\n"));
  145. return;
  146. }
  147. status = NtClose( AtcpHandle );
  148. AtcpHandle = NULL;
  149. if ( !NT_SUCCESS( status ) )
  150. {
  151. ATCP_DBGPRINT(("atcpCloseHandle: NtClose failed %lx\n",status));
  152. ATCP_ASSERT(0);
  153. }
  154. else
  155. {
  156. ATCP_DBGPRINT(("atcpCloseHandle: NtClose succeeded\n",status));
  157. }
  158. }
  159. //***
  160. //
  161. // Function: atcpAtkSetup
  162. // This is the entry point into the stack to tell the stack to
  163. // set up a context for this connection, to get a network address
  164. // for the dial-in client, server's zone name, and router address
  165. //
  166. // Parameters: pAtcpConn - connection context
  167. //
  168. // Return: status returned by NtDeviceIoControlFile
  169. //
  170. //***$
  171. DWORD
  172. atcpAtkSetup(
  173. IN PATCPCONN pAtcpConn,
  174. IN ULONG IoControlCode
  175. )
  176. {
  177. NTSTATUS status;
  178. IO_STATUS_BLOCK iosb;
  179. HANDLE Event;
  180. BYTE Buffer[sizeof(ARAP_SEND_RECV_INFO) + sizeof(ATCPINFO)];
  181. PARAP_SEND_RECV_INFO pSndRcvInfo;
  182. PATCPINFO pAtcpInfo;
  183. PATCP_SUPPRESS_INFO pSupprInfo;
  184. DWORD dwRetCode=NO_ERROR;
  185. RtlZeroMemory((PBYTE)Buffer, sizeof(Buffer));
  186. pSndRcvInfo = (PARAP_SEND_RECV_INFO)Buffer;
  187. pSndRcvInfo->StatusCode = (DWORD)-1;
  188. pSndRcvInfo->pDllContext = (PVOID)pAtcpConn;
  189. pSndRcvInfo->IoctlCode = IoControlCode;
  190. pSndRcvInfo->ClientAddr = pAtcpConn->ClientAddr;
  191. if (IoControlCode == IOCTL_ATCP_SETUP_CONNECTION)
  192. {
  193. pSndRcvInfo->DataLen = sizeof(ATCPINFO);
  194. }
  195. else if (IoControlCode == IOCTL_ATCP_SUPPRESS_BCAST)
  196. {
  197. // if we don't need to suppress broadcasts, done here
  198. if ((!pAtcpConn->SuppressRtmp) && (!pAtcpConn->SuppressAllBcast))
  199. {
  200. return(NO_ERROR);
  201. }
  202. pSndRcvInfo->DataLen = sizeof(ATCP_SUPPRESS_INFO);
  203. pSupprInfo = (PATCP_SUPPRESS_INFO)&pSndRcvInfo->Data[0];
  204. pSupprInfo->SuppressRtmp = pAtcpConn->SuppressRtmp;
  205. pSupprInfo->SuppressAllBcast = pAtcpConn->SuppressAllBcast;
  206. }
  207. else
  208. {
  209. pSndRcvInfo->DataLen = 0;
  210. }
  211. Event = CreateEvent(NULL, FALSE, FALSE, NULL);
  212. if (Event == NULL)
  213. {
  214. ATCP_DBGPRINT(("atcpAtkSetup: CreateEvent failed (%ld)\n",GetLastError()));
  215. return(ARAPERR_OUT_OF_RESOURCES);
  216. }
  217. status = NtDeviceIoControlFile(
  218. AtcpHandle,
  219. Event, // Event
  220. NULL, // ApcRoutine
  221. NULL, // ApcContext
  222. &iosb, // IoStatusBlock
  223. IoControlCode, // IoControlCode
  224. Buffer, // InputBuffer
  225. sizeof(Buffer), // InputBufferSize
  226. Buffer, // OutputBuffer
  227. sizeof(Buffer)); // OutputBufferSize
  228. if (status == STATUS_PENDING)
  229. {
  230. status = NtWaitForSingleObject(
  231. Event, // Handle
  232. TRUE, // Alertable
  233. NULL); // Timeout
  234. if (NT_SUCCESS(status))
  235. {
  236. status = iosb.Status;
  237. }
  238. }
  239. if (status != STATUS_SUCCESS)
  240. {
  241. ATCP_DBGPRINT(("atcpAtkSetup: NtDeviceIoControlFile failure (%lx)\n",
  242. status));
  243. dwRetCode = ARAPERR_IOCTL_FAILURE;
  244. }
  245. CloseHandle(Event);
  246. dwRetCode = pSndRcvInfo->StatusCode;
  247. if (dwRetCode != NO_ERROR)
  248. {
  249. ATCP_DBGPRINT(("atcpAtkSetup: ioctl %lx failed %ld\n",
  250. IoControlCode,dwRetCode));
  251. return(dwRetCode);
  252. }
  253. //
  254. // for SETUP ioctl, we have some info from stack we need to copy
  255. //
  256. if (IoControlCode == IOCTL_ATCP_SETUP_CONNECTION)
  257. {
  258. pAtcpInfo = (PATCPINFO)&pSndRcvInfo->Data[0];
  259. // get the client's address out
  260. EnterCriticalSection(&pAtcpConn->CritSect);
  261. pAtcpConn->AtalkContext = pSndRcvInfo->AtalkContext;
  262. pAtcpConn->ClientAddr = pSndRcvInfo->ClientAddr;
  263. LeaveCriticalSection(&pAtcpConn->CritSect);
  264. //
  265. // get the default router's address and the zone name
  266. //
  267. EnterCriticalSection( &AtcpCritSect );
  268. AtcpServerAddress = pAtcpInfo->ServerAddr;
  269. AtcpDefaultRouter = pAtcpInfo->DefaultRouterAddr;
  270. ATCP_ASSERT(pAtcpInfo->ServerZoneName[0] < ZONESTR_LEN);
  271. CopyMemory(&AtcpZoneName[1],
  272. &pAtcpInfo->ServerZoneName[1],
  273. pAtcpInfo->ServerZoneName[0]);
  274. AtcpZoneName[0] = pAtcpInfo->ServerZoneName[0];
  275. // got one more connection!
  276. AtcpNumConnections++;
  277. LeaveCriticalSection( &AtcpCritSect );
  278. }
  279. return(dwRetCode);
  280. }
  281. //***
  282. //
  283. // Function: atcpAllocConnection
  284. // This routine allocates an ATCP connection block, initializes
  285. // it with info provided by PPP engine.
  286. //
  287. // Parameters: pInfo - PPPCP_INIT info
  288. //
  289. // Return: pointer to ATCP connection if successful, NULL otherwise
  290. //
  291. //***$
  292. PATCPCONN
  293. atcpAllocConnection(
  294. IN PPPCP_INIT *pPppInit
  295. )
  296. {
  297. PATCPCONN pAtcpConn=NULL;
  298. pAtcpConn = (PATCPCONN)LocalAlloc(LPTR, sizeof(ATCPCONN));
  299. if (pAtcpConn == NULL)
  300. {
  301. ATCP_DBGPRINT(("atcpAllocConnection: malloc failed\n"));
  302. return(NULL);
  303. }
  304. memset( pAtcpConn, 0, sizeof(ATCPCONN) );
  305. pAtcpConn->Signature = ATCP_SIGNATURE;
  306. // by default, broadcasts are not suppressed
  307. pAtcpConn->SuppressRtmp = FALSE;
  308. pAtcpConn->SuppressAllBcast = FALSE;
  309. pAtcpConn->fLineUpDone = FALSE;
  310. InitializeCriticalSection( &pAtcpConn->CritSect );
  311. pAtcpConn->hPort = pPppInit->hPort;
  312. pAtcpConn->hConnection = pPppInit->hConnection;
  313. return(pAtcpConn);
  314. }
  315. //***
  316. //
  317. // Function: atcpParseRequest
  318. // This routine parses the incoming ATCP packet and prepares a
  319. // response as appropriate (Rej, Nak or Ack)
  320. //
  321. // AppleTalk-Address
  322. // 1 6 0 AT-NET(2) AT-Node (1)
  323. // Routing-Protocol
  324. // 2 4 0 0 (Routing protocol - last 2 bytes - can be 0, 1, 2, 3:
  325. // we only support 0)
  326. // Suppress-Broadcasts
  327. // 3 2 (to suppress all broadcasts)
  328. // 3 3 1 (to suppress RTMP bcasts. We don't support other types)
  329. // AT-Compression-Protocol
  330. // 4 4 Undefined!
  331. // Server-information
  332. // 6 Len .....
  333. // Zone-Information
  334. // 7 Len ZoneName
  335. // Default-Router-Address
  336. // 8 6 0 AT-NET(2) AT-Node (1)
  337. //
  338. //
  339. // Parameters: pAtcpConn - the connection
  340. // pReceiveBuf - PPP_CONFIG info: the request
  341. // pSendBuf - PPP_CONFIG info: our response
  342. // cbSendBuf - how big is the Data buffer for our response (for Rej)
  343. // ParseResult - array where we mark off options we saw
  344. // pfRejectingSomething - pointer to TRUE if Rejecting something
  345. //
  346. // Return: result of the operation
  347. //
  348. //***$
  349. DWORD
  350. atcpParseRequest(
  351. IN PATCPCONN pAtcpConn,
  352. IN PPP_CONFIG *pReceiveBuf,
  353. OUT PPP_CONFIG *pSendBuf,
  354. IN DWORD cbSendBuf,
  355. OUT BYTE ParseResult[ATCP_OPT_MAX_VAL+1],
  356. OUT BOOL *pfRejectingSomething
  357. )
  358. {
  359. PPP_OPTION UNALIGNED *pRequest;
  360. PPP_OPTION UNALIGNED *pReject;
  361. DWORD BytesLeftInSendBuf;
  362. PBYTE pOptData;
  363. USHORT OptDataLen;
  364. USHORT PktLen;
  365. USHORT RequestLen;
  366. USHORT UnParsedBytes;
  367. NET_ADDR ClientAddr;
  368. DWORD i;
  369. *pfRejectingSomething = FALSE;
  370. pRequest = (PPP_OPTION UNALIGNED* )pReceiveBuf->Data;
  371. pReject = (PPP_OPTION UNALIGNED* )pSendBuf->Data;
  372. BytesLeftInSendBuf = cbSendBuf;
  373. PktLen = WireToHostFormat16( pReceiveBuf->Length );
  374. UnParsedBytes = PktLen - PPP_CONFIG_HDR_LEN;
  375. // initialize for now to "nothing requested"
  376. for (i=0; i<ATCP_OPT_MAX_VAL; i++)
  377. {
  378. ParseResult[i] = ATCP_NOT_REQUESTED;
  379. }
  380. //
  381. // we loop until we have parsed all the bytes
  382. //
  383. while (UnParsedBytes > 0)
  384. {
  385. RequestLen = (USHORT)pRequest->Length;
  386. if (UnParsedBytes < RequestLen)
  387. {
  388. ATCP_DBGPRINT(("atcpParseRequest: too few bytes %d vs. %d\n",
  389. UnParsedBytes,RequestLen));
  390. return(ERROR_PPP_INVALID_PACKET);
  391. }
  392. //
  393. // assume we're going to accept this option. We'll overwrite if that's
  394. // not the case
  395. //
  396. ParseResult[pRequest->Type] = ATCP_ACK;
  397. // the point where the data portion for this option starts
  398. pOptData = &pRequest->Data[0];
  399. // remove the Type and Len bytes, remaining is option data
  400. OptDataLen = RequestLen - 2;
  401. #if 0
  402. ATCP_DBGPRINT(("atcpParseRequest: type %d OptLen %d (",
  403. pRequest->Type,OptDataLen));
  404. for (i=0; i<OptDataLen; i++)
  405. {
  406. DbgPrint(" 0x%x",pOptData[i]);
  407. }
  408. DbgPrint(" )\n");
  409. #endif
  410. //
  411. // now look at each of the options and see if we should reject it,
  412. // modify it or accept it (Rej, Nak or Ack)
  413. //
  414. switch (pRequest->Type)
  415. {
  416. //
  417. // client wants an appletalk address. We don't allow the client to
  418. // request which address he wants.
  419. //
  420. case ATCP_OPT_APPLETALK_ADDRESS:
  421. if (RequestLen != 6)
  422. {
  423. ATCP_DBGPRINT(("atcpParseRequest: AT_ADDR wrong pktlen %d\n",
  424. RequestLen));
  425. return(ERROR_PPP_INVALID_PACKET);
  426. }
  427. ClientAddr.ata_Network =
  428. WireToHostFormat16(&pOptData[1]);
  429. ClientAddr.ata_Node = (USHORT)pOptData[3];
  430. if ((ClientAddr.ata_Network == 0) ||
  431. (ClientAddr.ata_Node == 0) ||
  432. (ClientAddr.ata_Network != pAtcpConn->ClientAddr.ata_Network) ||
  433. (ClientAddr.ata_Node != pAtcpConn->ClientAddr.ata_Node))
  434. {
  435. ParseResult[pRequest->Type] = ATCP_NAK;
  436. }
  437. break;
  438. //
  439. // client wants some routing protocol. we don't send out Routing
  440. // info, so we should just Nak this option (unless the client also
  441. // is telling us not to send any routing info)
  442. //
  443. case ATCP_OPT_ROUTING_PROTOCOL:
  444. if (RequestLen < 4)
  445. {
  446. ATCP_DBGPRINT(("atcpParseRequest: ROUTING wrong pktlen %d\n",
  447. RequestLen));
  448. return(ERROR_PPP_INVALID_PACKET);
  449. }
  450. //
  451. // we don't send out Routing info, so attempt to negotiate any
  452. // other protocol should be Nak'ed
  453. //
  454. if ((*(USHORT *)&pOptData[0]) != ATCP_OPT_ROUTING_NONE)
  455. {
  456. ParseResult[pRequest->Type] = ATCP_NAK;
  457. }
  458. break;
  459. //
  460. // client wants to suppress broadcasts of some (or all) types of
  461. // DDP types.
  462. //
  463. case ATCP_OPT_SUPPRESS_BROADCAST:
  464. //
  465. // client wants us to suppress only some bcasts?
  466. //
  467. if (OptDataLen > 0)
  468. {
  469. // if requesting RTMP data suppression, we'll allow it
  470. if (pOptData[0] == DDPPROTO_RTMPRESPONSEORDATA)
  471. {
  472. pAtcpConn->SuppressRtmp = TRUE;
  473. }
  474. // hmm, some other protocol: sorry, no can do
  475. else
  476. {
  477. ATCP_DBGPRINT(("atcpParseRequest: Naking suppression %d\n",
  478. pOptData[0]));
  479. ParseResult[pRequest->Type] = ATCP_NAK;
  480. }
  481. }
  482. else
  483. {
  484. pAtcpConn->SuppressAllBcast = TRUE;
  485. }
  486. break;
  487. //
  488. // client wants to negotiate some compression. No compression
  489. // scheme is defined, so we just have to reject this option
  490. //
  491. case ATCP_OPT_AT_COMPRESSION_PROTOCOL:
  492. ATCP_DBGPRINT(("atcpParseRequest: COMPRESSION sending Rej\n"));
  493. if (BytesLeftInSendBuf >= RequestLen)
  494. {
  495. CopyMemory((PVOID)pReject, (PVOID)pRequest, RequestLen);
  496. BytesLeftInSendBuf -= RequestLen;
  497. }
  498. else
  499. {
  500. ATCP_DBGPRINT(("atcpParseRequest: PPP engine's buffer too small\n",
  501. RequestLen));
  502. return(ERROR_BUFFER_TOO_SMALL);
  503. }
  504. pReject = (PPP_OPTION UNALIGNED *)((BYTE* )pReject + RequestLen);
  505. *pfRejectingSomething = TRUE;
  506. ParseResult[pRequest->Type] = ATCP_REJ;
  507. break;
  508. //
  509. // for the following options, we just take note of the fact that
  510. // the client has requested it and we send the info over. Nothing
  511. // to negotiate in these options.
  512. // (We aren't supposed to Nak these either)
  513. //
  514. case ATCP_OPT_RESERVED:
  515. case ATCP_OPT_SERVER_INFORMATION:
  516. case ATCP_OPT_ZONE_INFORMATION:
  517. case ATCP_OPT_DEFAULT_ROUTER_ADDRESS:
  518. break;
  519. default:
  520. ATCP_DBGPRINT(("atcpParseRequest: unknown type %d\n",
  521. pRequest->Type));
  522. return(ERROR_PPP_INVALID_PACKET);
  523. }
  524. //
  525. // move to the next option
  526. //
  527. UnParsedBytes -= RequestLen;
  528. pRequest = (PPP_OPTION UNALIGNED *)((BYTE* )pRequest + RequestLen);
  529. }
  530. //
  531. // see if we are rejecting some option. If so, set some values
  532. //
  533. if (*pfRejectingSomething)
  534. {
  535. pSendBuf->Code = CONFIG_REJ;
  536. HostToWireFormat16( (USHORT)((PBYTE)pReject - (PBYTE)pSendBuf),
  537. pSendBuf->Length );
  538. ATCP_DUMP_BYTES("atcpParseRequest: Rejecting these options:",
  539. &pSendBuf->Data[0],
  540. (DWORD)WireToHostFormat16( pSendBuf->Length)-4);
  541. }
  542. return(NO_ERROR);
  543. }
  544. //***
  545. //
  546. // Function: atcpPrepareResponse
  547. // This routine prepares a response, depending on what all info
  548. // was parsed out from the client's request.
  549. //
  550. // Parameters: pAtcpConn - the connection
  551. // pSendBuf - PPP_CONFIG info: our response
  552. // cbSendBuf - how big is the Data buffer for our response
  553. // ParseResult - array where we have the parsed info
  554. //
  555. // Return: result of the operation
  556. //
  557. //***$
  558. DWORD
  559. atcpPrepareResponse(
  560. IN PATCPCONN pAtcpConn,
  561. OUT PPP_CONFIG *pSendBuf,
  562. IN DWORD cbSendBuf,
  563. OUT BYTE ParseResult[ATCP_OPT_MAX_VAL+1]
  564. )
  565. {
  566. DWORD dwRetCode=NO_ERROR;
  567. DWORD BytesLeftInSendBuf;
  568. PPP_OPTION UNALIGNED *pResponse;
  569. PBYTE pOptData;
  570. USHORT OptDataLen;
  571. USHORT OptionType;
  572. DWORD i;
  573. BOOL fNakingSomething=FALSE;
  574. BOOL fRequestingSomething=FALSE;
  575. BOOL fIncludeThisOption;
  576. pResponse = (PPP_OPTION UNALIGNED* )pSendBuf->Data;
  577. BytesLeftInSendBuf = cbSendBuf;
  578. // first find out if we are going to be Nak'ing anything
  579. for (OptionType=1; OptionType<ATCP_OPT_MAX_VAL; OptionType++ )
  580. {
  581. if (ParseResult[OptionType] == ATCP_NAK)
  582. {
  583. fNakingSomething = TRUE;
  584. }
  585. }
  586. //
  587. // go through our array to see which options we must send Nak to
  588. // (or construct Ack for the whole request)
  589. //
  590. for (OptionType=1; OptionType<ATCP_OPT_MAX_VAL; OptionType++ )
  591. {
  592. //
  593. // if this option is not (to be) requested, we don't send anything
  594. //
  595. if (ParseResult[OptionType] == ATCP_NOT_REQUESTED)
  596. {
  597. continue;
  598. }
  599. // if Nak'ing something and it's not this option to be Nak'ed, skip it
  600. if (fNakingSomething && (ParseResult[OptionType] != ATCP_NAK))
  601. {
  602. continue;
  603. }
  604. //
  605. // make sure we have at least 2 bytes for the OptionType and OptionLen
  606. //
  607. if (BytesLeftInSendBuf < 2)
  608. {
  609. ATCP_DBGPRINT(("atcpPrepareResponse: A: buf too small\n"));
  610. return(ERROR_BUFFER_TOO_SMALL);
  611. }
  612. BytesLeftInSendBuf -= 2;
  613. pOptData = &pResponse->Data[0];
  614. OptDataLen = 0;
  615. fIncludeThisOption = TRUE;
  616. switch (OptionType)
  617. {
  618. //
  619. // tell client (again) the client's network address
  620. //
  621. case ATCP_OPT_APPLETALK_ADDRESS:
  622. OptDataLen = sizeof(NET_ADDR);
  623. if (BytesLeftInSendBuf < OptDataLen)
  624. {
  625. ATCP_DBGPRINT(("atcpPrepareResponse: B: buf too small\n"));
  626. return(ERROR_BUFFER_TOO_SMALL);
  627. }
  628. // skip the reserved byte
  629. *pOptData++ = 0;
  630. //
  631. // if we are sending our REQUEST, send server's address
  632. //
  633. if (ParseResult[OptionType] == ATCP_REQ)
  634. {
  635. // put in the network address
  636. HostToWireFormat16(AtcpServerAddress.ata_Network, pOptData);
  637. pOptData += sizeof(USHORT);
  638. // put in the network node
  639. ATCP_ASSERT(pAtcpConn->ClientAddr.ata_Node != 0);
  640. *pOptData++ = (BYTE)AtcpServerAddress.ata_Node;
  641. fRequestingSomething = TRUE;
  642. }
  643. //
  644. // no, we must send the client's network address
  645. //
  646. else
  647. {
  648. // put in the network address
  649. HostToWireFormat16(pAtcpConn->ClientAddr.ata_Network, pOptData);
  650. pOptData += sizeof(USHORT);
  651. // put in the network node
  652. ATCP_ASSERT(pAtcpConn->ClientAddr.ata_Node != 0);
  653. *pOptData++ = (BYTE)pAtcpConn->ClientAddr.ata_Node;
  654. }
  655. break;
  656. //
  657. // tell client (again) that we support no routing info
  658. //
  659. case ATCP_OPT_ROUTING_PROTOCOL:
  660. OptDataLen = sizeof(USHORT);
  661. HostToWireFormat16(ATCP_OPT_ROUTING_NONE, pOptData);
  662. pOptData += sizeof(USHORT);
  663. break;
  664. //
  665. // tell client that we can suppress RTMP or all Bcast
  666. //
  667. case ATCP_OPT_SUPPRESS_BROADCAST:
  668. // if this is an ack, see if we have agreed to suppressing RTMP
  669. if (!fNakingSomething)
  670. {
  671. if (pAtcpConn->SuppressRtmp)
  672. {
  673. OptDataLen = 1;
  674. *pOptData++ = DDPPROTO_RTMPRESPONSEORDATA;
  675. }
  676. }
  677. break;
  678. //
  679. // we reach here only if are Acking the client's entire request
  680. //
  681. case ATCP_OPT_SERVER_INFORMATION:
  682. ATCP_ASSERT(ParseResult[OptionType] != ATCP_NAK);
  683. ATCP_ASSERT(!fNakingSomething);
  684. OptDataLen = sizeof(USHORT) + sizeof(DWORD) + AtcpServerName[0];
  685. if (BytesLeftInSendBuf < OptDataLen)
  686. {
  687. ATCP_DBGPRINT(("atcpPrepareResponse: C: buf too small\n"));
  688. return(ERROR_BUFFER_TOO_SMALL);
  689. }
  690. // copy the server's class-id
  691. HostToWireFormat16(ATCP_SERVER_CLASS, pOptData);
  692. pOptData += sizeof(USHORT);
  693. // copy the server's implementation-id
  694. HostToWireFormat32(ATCP_SERVER_IMPLEMENTATION_ID, pOptData);
  695. pOptData += sizeof(DWORD);
  696. // copy the server's name
  697. CopyMemory(pOptData, &AtcpServerName[1], AtcpServerName[0]);
  698. break;
  699. //
  700. // we reach here only if are Acking the client's entire request
  701. //
  702. case ATCP_OPT_ZONE_INFORMATION:
  703. ATCP_ASSERT(ParseResult[OptionType] != ATCP_NAK);
  704. ATCP_ASSERT(!fNakingSomething);
  705. // if we don't have a zone name, skip this option
  706. if (AtcpZoneName[0] == 0)
  707. {
  708. fIncludeThisOption = FALSE;
  709. break;
  710. }
  711. OptDataLen = AtcpZoneName[0];
  712. if (BytesLeftInSendBuf < OptDataLen)
  713. {
  714. ATCP_DBGPRINT(("atcpPrepareResponse: D: buf too small\n"));
  715. return(ERROR_BUFFER_TOO_SMALL);
  716. }
  717. // copy the zone name
  718. CopyMemory(pOptData, &AtcpZoneName[1], AtcpZoneName[0]);
  719. break;
  720. //
  721. // we reach here only if are Acking the client's entire request
  722. //
  723. case ATCP_OPT_DEFAULT_ROUTER_ADDRESS:
  724. ATCP_ASSERT(ParseResult[OptionType] != ATCP_NAK);
  725. ATCP_ASSERT(!fNakingSomething);
  726. // if we don't have a router address, skip this option
  727. if (AtcpDefaultRouter.ata_Network == 0)
  728. {
  729. fIncludeThisOption = FALSE;
  730. break;
  731. }
  732. OptDataLen = sizeof(NET_ADDR);
  733. if (BytesLeftInSendBuf < OptDataLen)
  734. {
  735. ATCP_DBGPRINT(("atcpPrepareResponse: E: buf too small\n"));
  736. return(ERROR_BUFFER_TOO_SMALL);
  737. }
  738. // skip the reserved byte
  739. *pOptData++ = 0;
  740. // put in the network address
  741. HostToWireFormat16(AtcpDefaultRouter.ata_Network, pOptData);
  742. pOptData += sizeof(USHORT);
  743. // put in the network node
  744. *pOptData++ = (BYTE)AtcpDefaultRouter.ata_Node;
  745. break;
  746. default:
  747. ATCP_DBGPRINT(("atcpPrepareResponse: opt %d ignored\n",OptionType));
  748. ATCP_ASSERT(0);
  749. break;
  750. }
  751. if (fIncludeThisOption)
  752. {
  753. BytesLeftInSendBuf -= OptDataLen;
  754. pResponse->Type = (BYTE)OptionType;
  755. pResponse->Length = OptDataLen + 2; // 2 = 1 Type byte + 1 Length byte
  756. pResponse = (PPP_OPTION UNALIGNED *)
  757. ((BYTE* )pResponse + pResponse->Length);
  758. }
  759. }
  760. HostToWireFormat16( (USHORT)((PBYTE)pResponse - (PBYTE)pSendBuf),
  761. pSendBuf->Length );
  762. pSendBuf->Code = (fNakingSomething) ? CONFIG_NAK :
  763. ((fRequestingSomething)? CONFIG_REQ : CONFIG_ACK);
  764. #if 0
  765. if (pSendBuf->Code == CONFIG_REQ)
  766. {
  767. ATCP_DUMP_BYTES("atcpParseRequest: Sending our request:",
  768. &pSendBuf->Data[0],
  769. (DWORD)WireToHostFormat16( pSendBuf->Length)-4);
  770. }
  771. else if (pSendBuf->Code == CONFIG_NAK)
  772. {
  773. ATCP_DUMP_BYTES("atcpParseRequest: Nak'ing these options:",
  774. &pSendBuf->Data[0],
  775. (DWORD)WireToHostFormat16( pSendBuf->Length)-4);
  776. }
  777. else
  778. {
  779. ATCP_DUMP_BYTES("atcpParseRequest: Ack packet from us to client:",
  780. &pSendBuf->Data[0],
  781. (DWORD)WireToHostFormat16( pSendBuf->Length)-4);
  782. }
  783. #endif
  784. return(NO_ERROR);
  785. }
  786. //***
  787. //
  788. // Function: atcpCloseAtalkConnection
  789. // This routine tells the stack to close this ATCP connection
  790. //
  791. // Parameters: pAtcpConn - the connection to close
  792. //
  793. // Return: result of the operation
  794. //
  795. //***$
  796. DWORD
  797. atcpCloseAtalkConnection(
  798. IN PATCPCONN pAtcpConn
  799. )
  800. {
  801. DWORD dwRetCode=NO_ERROR;
  802. // tell the stack that this connection is going away!
  803. dwRetCode = atcpAtkSetup(pAtcpConn, IOCTL_ATCP_CLOSE_CONNECTION);
  804. return(dwRetCode);
  805. }
  806. #if DBG
  807. //***
  808. //
  809. // Function: atcpDumpBytes
  810. // DEBUG only: This routine dumps out a given packet to debugger
  811. //
  812. // Parameters: Str - string, if any, to be printed out
  813. // Packet - packet!
  814. // PacketLen - how big is the packet
  815. //
  816. // Return: none
  817. //
  818. //***$
  819. VOID
  820. atcpDumpBytes(
  821. IN PBYTE Str,
  822. IN PBYTE Packet,
  823. IN DWORD PacketLen
  824. )
  825. {
  826. DWORD i;
  827. if (Str)
  828. {
  829. DbgPrint("%s: Packet size %ld\n ",Str,PacketLen);
  830. }
  831. else
  832. {
  833. DbgPrint("Packet size %ld\n ",PacketLen);
  834. }
  835. for (i=0; i<PacketLen; i++)
  836. {
  837. DbgPrint("%x ",Packet[i]);
  838. }
  839. DbgPrint("\n");
  840. }
  841. #endif
  842.