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.

1915 lines
45 KiB

  1. /*++
  2. Copyright (c) 1996 Microsoft Corporation
  3. Module Name:
  4. protocol.c
  5. Abstract:
  6. ipxwan protocol processing
  7. Author:
  8. Stefan Solomon 02/14/1996
  9. Revision History:
  10. --*/
  11. #include "precomp.h"
  12. #pragma hdrstop
  13. PCHAR Workstationp = "WORKSTATION";
  14. PCHAR NumberedRip = "NUMBERED RIP";
  15. PCHAR UnnumberedRip = "UNNUMBERED RIP";
  16. PCHAR OnDemand = "ON DEMAND, STATIC ROUTING";
  17. DWORD
  18. GeneratePacket(PACB acbp,
  19. PUCHAR ipxhdrp,
  20. UCHAR PacketType);
  21. ULONG
  22. GetRole(PUCHAR hdrp,
  23. PACB acbp);
  24. DWORD
  25. StartSlaveTimer(PACB acbp);
  26. DWORD
  27. ProcessInformationResponsePacket(PACB acbp,
  28. PUCHAR rcvhdrp);
  29. DWORD
  30. MakeTimerRequestPacket(PACB acbp,
  31. PUCHAR rcvhdrp,
  32. PUCHAR hdrp);
  33. DWORD
  34. MakeTimerResponsePacket(PACB acbp,
  35. PUCHAR rcvhdrp,
  36. PUCHAR hdrp);
  37. DWORD
  38. MakeInformationRequestPacket(PACB acbp,
  39. PUCHAR rcvhdrp,
  40. PUCHAR hdrp);
  41. DWORD
  42. MakeInformationResponsePacket(PACB acbp,
  43. PUCHAR rcvhdrp,
  44. PUCHAR hdrp);
  45. DWORD
  46. MakeNakPacket(PACB acbp,
  47. PUCHAR rcvhdrp,
  48. PUCHAR hdrp);
  49. DWORD
  50. SendReXmitPacket(PACB acbp,
  51. PWORK_ITEM wip);
  52. VOID
  53. fillpadding(PUCHAR padp,
  54. ULONG len);
  55. //** AcbFailure **
  56. // after this macro is called, clean-up for this adapter is done as follows:
  57. // ipxcp will delete the route (as in ndiswan route to ipx stack)
  58. // this will trigger an adapter deleted indication which will call StopIpxwanProtocol
  59. // this last call will flush the timer queue
  60. // when all pending work items are freed the adapter gets deleted
  61. #define AcbFailure(acbp) Trace(IPXWAN_TRACE, "IPXWAN Configuration failed for adapter %d\n", (acbp)->AdapterIndex);\
  62. (acbp)->OperState = OPER_STATE_DOWN;\
  63. IpxcpConfigDone((acbp)->ConnectionId, NULL, NULL, NULL, FALSE);
  64. UCHAR allffs[] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
  65. UCHAR allzeros[] = { 0, 0, 0, 0, 0, 0 };
  66. #define ERROR_IGNORE_PACKET 1
  67. #define ERROR_DISCONNECT 2
  68. #define ERROR_GENERATE_NAK 3
  69. /*++
  70. Function: StartIpxwanProtocol
  71. Descr: Called when an adapter is created.
  72. Starts IPXWAN negotiation on this adapter.
  73. Remark: >> called with the adapter lock held <<
  74. --*/
  75. VOID
  76. StartIpxwanProtocol(PACB acbp)
  77. {
  78. PWORK_ITEM wip;
  79. Trace(IPXWAN_TRACE, "StartIpxwanProtocol: Entered for adapter # %d\n", acbp->AdapterIndex);
  80. // initialize the IPXWAN states
  81. acbp->OperState = OPER_STATE_UP;
  82. acbp->AcbLevel = ACB_TIMER_LEVEL;
  83. acbp->AcbRole = ACB_UNKNOWN_ROLE;
  84. // initialize the IPXWAN database
  85. acbp->InterfaceType = IpxcpGetInterfaceType(acbp->ConnectionId);
  86. if((acbp->InterfaceType == IF_TYPE_STANDALONE_WORKSTATION_DIALOUT) ||
  87. (acbp->InterfaceType == IF_TYPE_ROUTER_WORKSTATION_DIALOUT)) {
  88. memset(acbp->InternalNetNumber, 0, 4);
  89. }
  90. else
  91. {
  92. IpxcpGetInternalNetNumber(acbp->InternalNetNumber);
  93. }
  94. acbp->IsExtendedNodeId = FALSE;
  95. acbp->SupportedRoutingTypes = 0;
  96. // set the routing type and node id to be sent in timer request
  97. switch(acbp->InterfaceType) {
  98. case IF_TYPE_WAN_ROUTER:
  99. case IF_TYPE_PERSONAL_WAN_ROUTER:
  100. if(EnableUnnumberedWanLinks) {
  101. memset(acbp->WNodeId, 0, 4);
  102. acbp->IsExtendedNodeId = TRUE;
  103. memcpy(acbp->ExtendedWNodeId, acbp->InternalNetNumber, 4);
  104. SET_UNNUMBERED_RIP(acbp->SupportedRoutingTypes);
  105. }
  106. else
  107. {
  108. memcpy(acbp->WNodeId, acbp->InternalNetNumber, 4);
  109. SET_NUMBERED_RIP(acbp->SupportedRoutingTypes);
  110. }
  111. break;
  112. case IF_TYPE_WAN_WORKSTATION:
  113. memcpy(acbp->WNodeId, acbp->InternalNetNumber, 4);
  114. SET_WORKSTATION(acbp->SupportedRoutingTypes);
  115. SET_NUMBERED_RIP(acbp->SupportedRoutingTypes);
  116. break;
  117. case IF_TYPE_ROUTER_WORKSTATION_DIALOUT:
  118. case IF_TYPE_STANDALONE_WORKSTATION_DIALOUT:
  119. memset(acbp->WNodeId, 0, 4);
  120. SET_WORKSTATION(acbp->SupportedRoutingTypes);
  121. break;
  122. default:
  123. Trace(IPXWAN_TRACE, "StartIpxwanProtocol: adpt# %d, Invalid interface type, DISCONNECT",
  124. acbp->AdapterIndex);
  125. SS_ASSERT(FALSE);
  126. AcbFailure(acbp);
  127. break;
  128. }
  129. // init negotiated values
  130. acbp->RoutingType = 0;
  131. memset(acbp->Network, 0, 4);
  132. memset(acbp->LocalNode, 0, 6);
  133. memset(acbp->RemoteNode, 0, 6);
  134. // no net number allocated yet
  135. acbp->AllocatedNetworkIndex = INVALID_NETWORK_INDEX;
  136. if(GeneratePacket(acbp, NULL, TIMER_REQUEST) != NO_ERROR) {
  137. Trace(IPXWAN_TRACE, "StartIpxwanProtocol: adpt# %d, ERROR: cannot generate TIMER_REQUEST, DISCONNECT\n",
  138. acbp->AdapterIndex);
  139. AcbFailure(acbp);
  140. }
  141. else
  142. {
  143. Trace(IPXWAN_TRACE, "StartIpxwanProtocol: adpt# %d, Sent TIMER_REQUEST\n",
  144. acbp->AdapterIndex);
  145. }
  146. }
  147. /*++
  148. Function: StopIpxwanProtocol
  149. Descr: Called when an adapter is deleted.
  150. Stops IPXWAN negotiation if still going.
  151. Remark: >> called with the adapter lock held <<
  152. --*/
  153. VOID
  154. StopIpxwanProtocol(PACB acbp)
  155. {
  156. Trace(IPXWAN_TRACE, "StopIpxwanProtocol: Entered for adapter # %d\n", acbp->AdapterIndex);
  157. acbp->OperState = OPER_STATE_DOWN;
  158. // remove all work items referencing this acb from the timer queue
  159. StopWiTimer(acbp);
  160. // free allocated wan net if any
  161. if(acbp->AllocatedNetworkIndex != INVALID_NETWORK_INDEX) {
  162. IpxcpReleaseWanNetNumber(acbp->AllocatedNetworkIndex);
  163. }
  164. }
  165. /*++
  166. Function: IpxwanConfigDone
  167. Descr: remove items referencing this acb from the timer queue
  168. sets the new configured values in the ipx stack
  169. Remark: >> called with the adapter lock held <<
  170. --*/
  171. VOID
  172. IpxwanConfigDone(PACB acbp)
  173. {
  174. DWORD rc;
  175. IPXWAN_INFO IpxwanInfo;
  176. StopWiTimer(acbp);
  177. memcpy(IpxwanInfo.Network, acbp->Network, 4);
  178. memcpy(IpxwanInfo.LocalNode, acbp->LocalNode, 6);
  179. memcpy(IpxwanInfo.RemoteNode, acbp->RemoteNode, 6);
  180. rc = IpxWanSetAdapterConfiguration(acbp->AdapterIndex,
  181. &IpxwanInfo);
  182. if(rc != NO_ERROR) {
  183. Trace(IPXWAN_TRACE, "IpxwanConfigDone: Error %d in IpxWanSetAdapterConfiguration\n",
  184. rc);
  185. AcbFailure(acbp);
  186. SS_ASSERT(FALSE);
  187. }
  188. else
  189. {
  190. IpxcpConfigDone(acbp->ConnectionId,
  191. acbp->Network,
  192. acbp->LocalNode,
  193. acbp->RemoteNode,
  194. TRUE);
  195. Trace(IPXWAN_TRACE,"\n*** IPXWAN final configuration ***");
  196. Trace(IPXWAN_TRACE," Network: %.2x%.2x%.2x%.2x\n",
  197. acbp->Network[0],
  198. acbp->Network[1],
  199. acbp->Network[2],
  200. acbp->Network[3]);
  201. Trace(IPXWAN_TRACE," LocalNode: %.2x%.2x%.2x%.2x%.2x%.2x",
  202. acbp->LocalNode[0],
  203. acbp->LocalNode[1],
  204. acbp->LocalNode[2],
  205. acbp->LocalNode[3],
  206. acbp->LocalNode[4],
  207. acbp->LocalNode[5]);
  208. Trace(IPXWAN_TRACE," RemoteNode: %.2x%.2x%.2x%.2x%.2x%.2x",
  209. acbp->RemoteNode[0],
  210. acbp->RemoteNode[1],
  211. acbp->RemoteNode[2],
  212. acbp->RemoteNode[3],
  213. acbp->RemoteNode[4],
  214. acbp->RemoteNode[5]);
  215. }
  216. }
  217. /*++
  218. Function: ProcessReceivedPacket
  219. Descr:
  220. Remark: >> called with the adapter lock held <<
  221. --*/
  222. VOID
  223. ProcessReceivedPacket(PACB acbp,
  224. PWORK_ITEM wip)
  225. {
  226. PUCHAR ipxhdrp; // ipx header
  227. PUCHAR wanhdrp; // ipx wan header
  228. PUCHAR opthdrp; // option header
  229. DWORD rc = NO_ERROR;
  230. USHORT pktlen;
  231. ULONG role;
  232. USHORT rcvsocket;
  233. PCHAR Slavep = "SLAVE";
  234. PCHAR Masterp = "MASTER";
  235. if(acbp->OperState == OPER_STATE_DOWN) {
  236. return;
  237. }
  238. // validate packet
  239. ipxhdrp = wip->Packet;
  240. // check the packet length
  241. GETSHORT2USHORT(&pktlen, ipxhdrp + IPXH_LENGTH);
  242. if(pktlen > MAX_IPXWAN_PACKET_LEN) {
  243. // bad length packet
  244. Trace(IPXWAN_TRACE, "ProcessReceivedPacket: Reject packet because of invalid length %d\n", pktlen);
  245. return;
  246. }
  247. // check remote socket and confidence id
  248. GETSHORT2USHORT(&rcvsocket, ipxhdrp + IPXH_SRCSOCK);
  249. if(rcvsocket != IPXWAN_SOCKET) {
  250. Trace(IPXWAN_TRACE, "ProcessReceivedPacket: Reject packet because of invalid socket %x\n", rcvsocket);
  251. return;
  252. }
  253. wanhdrp = ipxhdrp + IPXH_HDRSIZE;
  254. if(memcmp(wanhdrp + WIDENTIFIER,
  255. IPXWAN_CONFIDENCE_ID,
  256. 4)) {
  257. // no confidence
  258. Trace(IPXWAN_TRACE, "ProcessReceivedPacket: Reject packet because of invalid confidence id\n");
  259. return;
  260. }
  261. switch(*(wanhdrp + WPACKET_TYPE)) {
  262. case TIMER_REQUEST:
  263. role = GetRole(ipxhdrp, acbp);
  264. switch(role) {
  265. case ACB_SLAVE_ROLE:
  266. Trace(IPXWAN_TRACE, "ProcessReceivedPacket: Rcvd TIMER_REQUEST adpt# %d, local role %s",
  267. acbp->AdapterIndex,
  268. Slavep);
  269. acbp->AcbRole = ACB_SLAVE_ROLE;
  270. acbp->RoutingType = 0;
  271. if(acbp->AcbLevel != ACB_TIMER_LEVEL) {
  272. acbp->AcbLevel = ACB_TIMER_LEVEL;
  273. }
  274. rc = GeneratePacket(acbp, ipxhdrp, TIMER_RESPONSE);
  275. switch(rc) {
  276. case NO_ERROR:
  277. acbp->AcbLevel = ACB_INFO_LEVEL;
  278. // start the slave timeout
  279. if(StartSlaveTimer(acbp) != NO_ERROR) {
  280. Trace(IPXWAN_TRACE, "ProcessReceivedPacket: DISCONNECT adpt# %d: cannot start slave timer",
  281. acbp->AdapterIndex);
  282. AcbFailure(acbp);
  283. }
  284. Trace(IPXWAN_TRACE, "ProcessReceivedPacket: TIMER_RESPONSE sent OK on adpt # %d",
  285. acbp->AdapterIndex);
  286. break;
  287. case ERROR_DISCONNECT:
  288. Trace(IPXWAN_TRACE, "ProcessReceivedPacket: DISCONNECT: Error generating TIMER_RESPONSE on adpt# %d",
  289. acbp->AdapterIndex);
  290. AcbFailure(acbp);
  291. break;
  292. case ERROR_IGNORE_PACKET:
  293. default:
  294. Trace(IPXWAN_TRACE, "ProcessReceivedPacket: Ignore received TIMER_REQUEST on adpt# %d",
  295. acbp->AdapterIndex);
  296. break;
  297. }
  298. case ACB_MASTER_ROLE:
  299. if(acbp->AcbLevel != ACB_TIMER_LEVEL) {
  300. // ignore
  301. Trace(IPXWAN_TRACE, "ProcessReceivedPacket: ignore TIMER_REQUEST on adpt# %d because not at TIMER LEVEL",
  302. acbp->AdapterIndex);
  303. return;
  304. }
  305. else
  306. {
  307. acbp->AcbRole = ACB_MASTER_ROLE;
  308. Trace(IPXWAN_TRACE, "ProcessReceivedPacket: Rcvd TIMER_REQUEST adpt# %d, local role %s",
  309. acbp->AdapterIndex,
  310. Masterp);
  311. }
  312. break;
  313. default:
  314. Trace(IPXWAN_TRACE, "ProcessReceivedPacket: DISCONNECT adpt# %d: Unknown role with rcvd TIMER_REQUEST",
  315. acbp->AdapterIndex);
  316. AcbFailure(acbp);
  317. }
  318. break;
  319. case TIMER_RESPONSE:
  320. Trace(IPXWAN_TRACE, "ProcessReceivedPacket: Rcvd TIMER_RESPONSE on adpt# %d",
  321. acbp->AdapterIndex);
  322. // validate
  323. if((acbp->AcbRole == ACB_SLAVE_ROLE) ||
  324. !(acbp->AcbLevel == ACB_TIMER_LEVEL)) {
  325. Trace(IPXWAN_TRACE, "ProcessReceivedPacket: Rcvd TIMER_RESPONSE, DISCONNECT adpt# %d: role not MASTER or state not TIMER LEVEL",
  326. acbp->AdapterIndex);
  327. AcbFailure(acbp);
  328. }
  329. else if(*(wanhdrp + WSEQUENCE_NUMBER) == acbp->ReXmitSeqNo) {
  330. // rfc 1634 - link delay calculation
  331. acbp->LinkDelay = (USHORT)((GetTickCount() - acbp->TReqTimeStamp) * 6);
  332. rc = GeneratePacket(acbp, ipxhdrp, INFORMATION_REQUEST);
  333. switch(rc) {
  334. case NO_ERROR:
  335. acbp->AcbLevel = ACB_INFO_LEVEL;
  336. acbp->AcbRole = ACB_MASTER_ROLE;
  337. Trace(IPXWAN_TRACE, "ProcessReceivedPacket: INFORMATION_REQUEST sent OK on adpt # %d",
  338. acbp->AdapterIndex);
  339. break;
  340. case ERROR_DISCONNECT:
  341. Trace(IPXWAN_TRACE, "ProcessReceivedPacket: DISCONNECT adpt# %d: Error generating INFORMATION_REQUEST",
  342. acbp->AdapterIndex);
  343. AcbFailure(acbp);
  344. break;
  345. case ERROR_IGNORE_PACKET:
  346. default:
  347. Trace(IPXWAN_TRACE, "ProcessReceivedPacket: Ignore received TIMER_RESPONSE on adpt# %d",
  348. acbp->AdapterIndex);
  349. break;
  350. }
  351. }
  352. else
  353. {
  354. Trace(IPXWAN_TRACE, "ProcessReceivedPacket: Ignore TIMER RESPONSE and adpt# %d, non-matching seq no",
  355. acbp->AdapterIndex);
  356. }
  357. break;
  358. case INFORMATION_REQUEST:
  359. Trace(IPXWAN_TRACE, "ProcessReceivedPacket: Rcvd INFORMATION_REQUEST on adpt# %d",
  360. acbp->AdapterIndex);
  361. if((acbp->AcbLevel == ACB_INFO_LEVEL) && (acbp->AcbRole == ACB_SLAVE_ROLE)) {
  362. rc = GeneratePacket(acbp, ipxhdrp, INFORMATION_RESPONSE);
  363. switch(rc) {
  364. case NO_ERROR:
  365. acbp->AcbLevel = ACB_CONFIGURED_LEVEL;
  366. Trace(IPXWAN_TRACE, "ProcessReceivedPacket: INFORMATION_RESPONSE sent OK on adpt # %d",
  367. acbp->AdapterIndex);
  368. IpxwanConfigDone(acbp);
  369. // stop the slave timer
  370. StopWiTimer(acbp);
  371. break;
  372. case ERROR_DISCONNECT:
  373. Trace(IPXWAN_TRACE, "ProcessReceivedPacket: DISCONNECT adpt# %d: Error processing rcvd INFORMATION_REQUEST",
  374. acbp->AdapterIndex);
  375. AcbFailure(acbp);
  376. break;
  377. case ERROR_IGNORE_PACKET:
  378. default:
  379. Trace(IPXWAN_TRACE, "ProcessReceivedPacket: Ignore rcvd INFORMATION_REQUEST on adpt# %d",
  380. acbp->AdapterIndex);
  381. break;
  382. }
  383. }
  384. else
  385. {
  386. Trace(IPXWAN_TRACE, "ProcessReceivedPacket: DISCONNECT on rcvd INFORMATION_REQUEST on adpt# %d\nState not INFO LEVEL or Role not SLAVE\n",
  387. acbp->AdapterIndex);
  388. AcbFailure(acbp);
  389. }
  390. break;
  391. case INFORMATION_RESPONSE:
  392. Trace(IPXWAN_TRACE, "ProcessReceivedPacket: Rcvd INFORMATION_RESPONSE on adpt# %d",
  393. acbp->AdapterIndex);
  394. if((acbp->AcbLevel == ACB_INFO_LEVEL) && (acbp->AcbRole == ACB_MASTER_ROLE)) {
  395. if(*(wanhdrp + WSEQUENCE_NUMBER) == acbp->ReXmitSeqNo) {
  396. rc = ProcessInformationResponsePacket(acbp, wip->Packet);
  397. switch(rc) {
  398. case NO_ERROR:
  399. acbp->AcbLevel = ACB_CONFIGURED_LEVEL;
  400. IpxwanConfigDone(acbp);
  401. break;
  402. case ERROR_DISCONNECT:
  403. Trace(IPXWAN_TRACE, "ProcessReceivedPacket: DISCONNECT adpt# %d: Error processing rcvd INFORMATION_RESPONSE",
  404. acbp->AdapterIndex);
  405. AcbFailure(acbp);
  406. break;
  407. case ERROR_IGNORE_PACKET:
  408. default:
  409. Trace(IPXWAN_TRACE, "ProcessReceivedPacket: Ignore rcvd INFORMATION_RESPONSE on adpt# %d",
  410. acbp->AdapterIndex);
  411. break;
  412. }
  413. }
  414. }
  415. else
  416. {
  417. Trace(IPXWAN_TRACE, "ProcessReceivedPacket: DISCONNECT on rcvd INFORMATION_RESPONSE on adpt# %d\nState not INFO LEVEL or Role not MASTER\n",
  418. acbp->AdapterIndex);
  419. AcbFailure(acbp);
  420. }
  421. break;
  422. case NAK:
  423. Trace(IPXWAN_TRACE, "ProcessReceivedPacket: Rcvd NAK on adpt# %d, DISCONNECT\n",
  424. acbp->AdapterIndex);
  425. AcbFailure(acbp);
  426. break;
  427. default:
  428. Trace(IPXWAN_TRACE, "ProcessReceivedPacket: Rcvd unknown packet on adpt# %d, IGNORE\n",
  429. acbp->AdapterIndex);
  430. break;
  431. }
  432. }
  433. /*++
  434. Function: ProcessReXmitPacket
  435. Descr:
  436. Remark: >> called with the adapter lock held <<
  437. --*/
  438. VOID
  439. ProcessReXmitPacket(PWORK_ITEM wip)
  440. {
  441. PACB acbp;
  442. UCHAR WPacketType;
  443. DWORD rc;
  444. PCHAR PacketTypep;
  445. acbp = wip->acbp;
  446. if(acbp->OperState != OPER_STATE_UP) {
  447. FreeWorkItem(wip);
  448. return;
  449. }
  450. WPacketType = *(wip->Packet + IPXH_HDRSIZE + WPACKET_TYPE);
  451. if(!((acbp->AcbLevel == ACB_TIMER_LEVEL) && (WPacketType == TIMER_REQUEST)) &&
  452. !((acbp->AcbLevel == ACB_INFO_LEVEL) && (WPacketType == INFORMATION_REQUEST))) {
  453. FreeWorkItem(wip);
  454. return;
  455. }
  456. switch(wip->WiState) {
  457. case WI_SEND_COMPLETED:
  458. StartWiTimer(wip, REXMIT_TIMEOUT);
  459. acbp->RefCount++;
  460. break;
  461. case WI_TIMEOUT_COMPLETED:
  462. switch(WPacketType) {
  463. case TIMER_REQUEST:
  464. PacketTypep = "TIMER_REQUEST";
  465. break;
  466. case INFORMATION_REQUEST:
  467. default:
  468. PacketTypep = "INFORMATION_REQUEST";
  469. break;
  470. }
  471. if(acbp->ReXmitCount) {
  472. Trace(IPXWAN_TRACE, "ProcessReXmitPacket: Re-send %s on adpt# %d\n",
  473. PacketTypep,
  474. acbp->AdapterIndex);
  475. if(SendReXmitPacket(acbp, wip) != NO_ERROR) {
  476. Trace(IPXWAN_TRACE, "ProcessReXmitPacket: failed to send on adpt# %d, DISCONNECT\n",
  477. acbp->AdapterIndex);
  478. AcbFailure(acbp);
  479. }
  480. }
  481. else
  482. {
  483. Trace(IPXWAN_TRACE, "ProcessReXmitPacket: Exhausted retry limit for sending %s on adpt# %d, DISCONNECT\n",
  484. PacketTypep,
  485. acbp->AdapterIndex);
  486. AcbFailure(acbp);
  487. }
  488. break;
  489. default:
  490. SS_ASSERT(FALSE);
  491. break;
  492. }
  493. }
  494. /*++
  495. Function: ProcessTimeout
  496. Descr:
  497. Remark: >> called with the adapter lock held <<
  498. --*/
  499. VOID
  500. ProcessTimeout(PWORK_ITEM wip)
  501. {
  502. PACB acbp;
  503. UCHAR WPacketType;
  504. DWORD rc;
  505. acbp = wip->acbp;
  506. FreeWorkItem(wip);
  507. if(acbp->OperState != OPER_STATE_UP) {
  508. return;
  509. }
  510. if((acbp->AcbRole == ACB_SLAVE_ROLE) && (acbp->AcbLevel != ACB_CONFIGURED_LEVEL)) {
  511. AcbFailure(acbp);
  512. }
  513. }
  514. /*++
  515. Function: SendReXmitPacket
  516. Descr: adjusts the rexmit count and seq no and sends the packet
  517. Remark: >> called with adapter lock held <<
  518. --*/
  519. DWORD
  520. SendReXmitPacket(PACB acbp,
  521. PWORK_ITEM wip)
  522. {
  523. DWORD rc;
  524. // set the wi rexmit fields
  525. acbp->ReXmitCount--;
  526. acbp->ReXmitSeqNo++;
  527. *(wip->Packet + IPXH_HDRSIZE + WSEQUENCE_NUMBER) = acbp->ReXmitSeqNo;
  528. rc = SendSubmit(wip);
  529. if(rc == NO_ERROR) {
  530. acbp->RefCount++;
  531. }
  532. acbp->TReqTimeStamp = GetTickCount();
  533. return rc;
  534. }
  535. /*++
  536. Function: GeneratePacket
  537. Descr: allocate the work item,
  538. constructs the response packet to the received packet (if any)
  539. send the response as a rexmit packet or as a one time send packet
  540. Returns: NO_ERROR
  541. ERROR_IGNORE_PACKET - ignore the received packet
  542. ERROR_DISCONNECT - disconnect the adapter because of fatal error
  543. Remark: >> called with the adapter lock held <<
  544. --*/
  545. DWORD
  546. GeneratePacket(PACB acbp,
  547. PUCHAR ipxhdrp,
  548. UCHAR PacketType)
  549. {
  550. DWORD rc;
  551. ULONG WiType;
  552. PWORK_ITEM wip;
  553. if((wip = AllocateWorkItem(SEND_PACKET_TYPE)) == NULL) {
  554. return ERROR_DISCONNECT;
  555. }
  556. switch(PacketType) {
  557. case TIMER_REQUEST:
  558. rc = MakeTimerRequestPacket(acbp, ipxhdrp, wip->Packet);
  559. break;
  560. case TIMER_RESPONSE:
  561. rc = MakeTimerResponsePacket(acbp, ipxhdrp, wip->Packet);
  562. break;
  563. case INFORMATION_REQUEST:
  564. rc = MakeInformationRequestPacket(acbp, ipxhdrp, wip->Packet);
  565. break;
  566. case INFORMATION_RESPONSE:
  567. rc = MakeInformationResponsePacket(acbp, ipxhdrp, wip->Packet);
  568. break;
  569. default:
  570. rc = ERROR_DISCONNECT;
  571. break;
  572. }
  573. if(rc == NO_ERROR) {
  574. // no error making the packet -> try to send it
  575. wip->AdapterIndex = acbp->AdapterIndex;
  576. wip->WiState = WI_INIT;
  577. switch(PacketType) {
  578. case TIMER_REQUEST:
  579. case INFORMATION_REQUEST:
  580. // re-xmit packet type
  581. wip->ReXmitPacket = TRUE;
  582. // create a reference to the adapter CB
  583. wip->acbp = acbp;
  584. acbp->ReXmitCount = MAX_REXMIT_COUNT;
  585. acbp->ReXmitSeqNo = 0xFF;
  586. if(SendReXmitPacket(acbp, wip) != NO_ERROR) {
  587. rc = ERROR_DISCONNECT;
  588. }
  589. break;
  590. case TIMER_RESPONSE:
  591. case INFORMATION_RESPONSE:
  592. default:
  593. // one time send
  594. wip->ReXmitPacket = FALSE;
  595. if(SendSubmit(wip) != NO_ERROR) {
  596. rc = ERROR_DISCONNECT;
  597. }
  598. break;
  599. }
  600. }
  601. if(rc != NO_ERROR) {
  602. // error making or trying to send the packet
  603. if(rc != ERROR_GENERATE_NAK) {
  604. FreeWorkItem(wip);
  605. }
  606. else
  607. {
  608. // if we were requested to generate a NAK packet instead, try to it it
  609. MakeNakPacket(acbp, ipxhdrp, wip->Packet);
  610. wip->ReXmitPacket = FALSE;
  611. if(SendSubmit(wip) != NO_ERROR) {
  612. FreeWorkItem(wip);
  613. rc = ERROR_DISCONNECT;
  614. }
  615. else
  616. {
  617. rc = ERROR_IGNORE_PACKET;
  618. }
  619. }
  620. }
  621. return rc;
  622. }
  623. ULONG
  624. GetRole(PUCHAR hdrp,
  625. PACB acbp)
  626. {
  627. ULONG RemoteWNodeId;
  628. ULONG LocalWNodeId;
  629. PUCHAR ipxwanhdrp = hdrp + IPXH_HDRSIZE;
  630. PUCHAR optp;
  631. USHORT optlen;
  632. BOOL IsRemoteExtendedNodeId = FALSE;
  633. ULONG RemoteExtendedWNodeId;
  634. ULONG LocalExtendedWNodeId;
  635. ULONG i;
  636. GETLONG2ULONG(&LocalWNodeId, acbp->WNodeId);
  637. GETLONG2ULONG(&RemoteWNodeId, ipxwanhdrp + WNODE_ID);
  638. if((LocalWNodeId == 0) && (RemoteWNodeId == 0)) {
  639. // check if received timer request has the extended node id option
  640. for(optp = ipxwanhdrp + IPXWAN_HDRSIZE, i=0;
  641. i < *(ipxwanhdrp + WNUM_OPTIONS);
  642. i++)
  643. {
  644. if(*(optp + WOPTION_NUMBER) == EXTENDED_NODE_ID_OPTION) {
  645. IsRemoteExtendedNodeId = TRUE;
  646. GETLONG2ULONG(&RemoteExtendedWNodeId, optp + WOPTION_DATA);
  647. break;
  648. }
  649. GETSHORT2USHORT(&optlen, optp + WOPTION_DATA_LEN);
  650. optp += OPTION_HDRSIZE + optlen;
  651. }
  652. if(acbp->IsExtendedNodeId && IsRemoteExtendedNodeId) {
  653. GETLONG2ULONG(&LocalExtendedWNodeId, acbp->ExtendedWNodeId);
  654. if(LocalExtendedWNodeId > RemoteExtendedWNodeId) {
  655. return ACB_MASTER_ROLE;
  656. }
  657. else if(LocalExtendedWNodeId < RemoteExtendedWNodeId) {
  658. return ACB_SLAVE_ROLE;
  659. }
  660. else
  661. {
  662. return ACB_UNKNOWN_ROLE;
  663. }
  664. }
  665. else if(acbp->IsExtendedNodeId) {
  666. return ACB_MASTER_ROLE;
  667. }
  668. else if(IsRemoteExtendedNodeId) {
  669. return ACB_SLAVE_ROLE;
  670. }
  671. else
  672. {
  673. return ACB_UNKNOWN_ROLE;
  674. }
  675. }
  676. else if(LocalWNodeId > RemoteWNodeId) {
  677. return ACB_MASTER_ROLE;
  678. }
  679. else if(LocalWNodeId < RemoteWNodeId) {
  680. return ACB_SLAVE_ROLE;
  681. }
  682. else
  683. {
  684. return ACB_UNKNOWN_ROLE;
  685. }
  686. }
  687. /*++
  688. Function: MakeTimerRequestPacket
  689. Descr:
  690. Arguments: acbp - ptr to adapter CB
  691. hdrp - ptr to the new packet to be made
  692. --*/
  693. DWORD
  694. MakeTimerRequestPacket(PACB acbp,
  695. PUCHAR rcvhdrp,
  696. PUCHAR hdrp)
  697. {
  698. PUCHAR ipxwanhdrp;
  699. PUCHAR optp;
  700. USHORT padlen = TIMER_REQUEST_PACKET_LENGTH;
  701. // set IPX Header
  702. memcpy(hdrp + IPXH_CHECKSUM, allffs, 2);
  703. PUTUSHORT2SHORT(hdrp + IPXH_LENGTH, TIMER_REQUEST_PACKET_LENGTH);
  704. *(hdrp + IPXH_XPORTCTL) = 0;
  705. *(hdrp + IPXH_PKTTYPE) = IPX_PACKET_EXCHANGE_TYPE;
  706. memcpy(hdrp + IPXH_DESTNET, allzeros, 4);
  707. memcpy(hdrp + IPXH_DESTNODE, allffs, 6);
  708. PUTUSHORT2SHORT(hdrp + IPXH_DESTSOCK, IPXWAN_SOCKET);
  709. memcpy(hdrp + IPXH_SRCNET, allzeros, 4);
  710. memcpy(hdrp + IPXH_SRCNODE, allzeros, 6);
  711. PUTUSHORT2SHORT(hdrp + IPXH_DESTSOCK, IPXWAN_SOCKET);
  712. // set IPXWAN Header
  713. ipxwanhdrp = hdrp + IPXH_HDRSIZE;
  714. memcpy(ipxwanhdrp + WIDENTIFIER, IPXWAN_CONFIDENCE_ID, 4);
  715. *(ipxwanhdrp + WPACKET_TYPE) = TIMER_REQUEST;
  716. memcpy(ipxwanhdrp + WNODE_ID, acbp->WNodeId, 4);
  717. // the sequence number is written when the packet gets sent
  718. *(ipxwanhdrp + WNUM_OPTIONS) = 0;
  719. padlen -= (IPXH_HDRSIZE + IPXWAN_HDRSIZE);
  720. // set OPTIONS
  721. optp = ipxwanhdrp + IPXWAN_HDRSIZE;
  722. if(IS_WORKSTATION(acbp->SupportedRoutingTypes)) {
  723. (*(ipxwanhdrp + WNUM_OPTIONS))++;
  724. *(optp + WOPTION_NUMBER) = ROUTING_TYPE_OPTION;
  725. *(optp + WACCEPT_OPTION) = YES;
  726. PUTUSHORT2SHORT(optp + WOPTION_DATA_LEN, ROUTING_TYPE_DATA_LEN);
  727. *(optp + WOPTION_DATA) = WORKSTATION_ROUTING_TYPE;
  728. optp += OPTION_HDRSIZE + ROUTING_TYPE_DATA_LEN;
  729. padlen -= (OPTION_HDRSIZE + ROUTING_TYPE_DATA_LEN);
  730. }
  731. if(IS_NUMBERED_RIP(acbp->SupportedRoutingTypes)) {
  732. (*(ipxwanhdrp + WNUM_OPTIONS))++;
  733. *(optp + WOPTION_NUMBER) = ROUTING_TYPE_OPTION;
  734. *(optp + WACCEPT_OPTION) = YES;
  735. PUTUSHORT2SHORT(optp + WOPTION_DATA_LEN, ROUTING_TYPE_DATA_LEN);
  736. *(optp + WOPTION_DATA) = NUMBERED_RIP_ROUTING_TYPE;
  737. optp += OPTION_HDRSIZE + ROUTING_TYPE_DATA_LEN;
  738. padlen -= (OPTION_HDRSIZE + ROUTING_TYPE_DATA_LEN);
  739. }
  740. if(IS_UNNUMBERED_RIP(acbp->SupportedRoutingTypes)) {
  741. (*(ipxwanhdrp + WNUM_OPTIONS))++;
  742. *(optp + WOPTION_NUMBER) = ROUTING_TYPE_OPTION;
  743. *(optp + WACCEPT_OPTION) = YES;
  744. PUTUSHORT2SHORT(optp + WOPTION_DATA_LEN, ROUTING_TYPE_DATA_LEN);
  745. *(optp + WOPTION_DATA) = UNNUMBERED_RIP_ROUTING_TYPE;
  746. optp += OPTION_HDRSIZE + ROUTING_TYPE_DATA_LEN;
  747. padlen -= (OPTION_HDRSIZE + ROUTING_TYPE_DATA_LEN);
  748. }
  749. if(acbp->IsExtendedNodeId) {
  750. (*(ipxwanhdrp + WNUM_OPTIONS))++;
  751. *(optp + WOPTION_NUMBER) = EXTENDED_NODE_ID_OPTION;
  752. *(optp + WACCEPT_OPTION) = YES;
  753. PUTUSHORT2SHORT(optp + WOPTION_DATA_LEN, EXTENDED_NODE_ID_DATA_LEN);
  754. memcpy(optp + WOPTION_DATA, acbp->ExtendedWNodeId, EXTENDED_NODE_ID_DATA_LEN);
  755. optp += OPTION_HDRSIZE + EXTENDED_NODE_ID_DATA_LEN;
  756. padlen -= (OPTION_HDRSIZE + EXTENDED_NODE_ID_DATA_LEN);
  757. }
  758. // PAD
  759. padlen -= OPTION_HDRSIZE;
  760. (*(ipxwanhdrp + WNUM_OPTIONS))++;
  761. *(optp + WOPTION_NUMBER) = PAD_OPTION;
  762. *(optp + WACCEPT_OPTION) = YES;
  763. PUTUSHORT2SHORT(optp + WOPTION_DATA_LEN, padlen);
  764. fillpadding(optp + WOPTION_DATA, padlen);
  765. return NO_ERROR;
  766. }
  767. /*++
  768. Function: MakeTimerResponsePacket
  769. Descr:
  770. Arguments: acbp - ptr to adapter CB
  771. rcvhdrp - ptr to the received TIMER_REQUEST packet
  772. hdrp - ptr to the new packet to be made
  773. --*/
  774. DWORD
  775. MakeTimerResponsePacket(PACB acbp,
  776. PUCHAR rcvhdrp,
  777. PUCHAR hdrp)
  778. {
  779. USHORT rcvlen;
  780. USHORT optlen;
  781. PUCHAR ipxwanhdrp;
  782. PUCHAR optp;
  783. ULONG RemoteWNodeId;
  784. ULONG i;
  785. Trace(IPXWAN_TRACE, "MakeTimerResponsePacket: Entered adapter # %d", acbp->AdapterIndex);
  786. // check received packet length
  787. GETSHORT2USHORT(&rcvlen, rcvhdrp + IPXH_LENGTH);
  788. if(rcvlen < TIMER_REQUEST_PACKET_LENGTH) {
  789. return ERROR_IGNORE_PACKET;
  790. }
  791. memcpy(hdrp, rcvhdrp, rcvlen);
  792. // set IPX Header
  793. memcpy(hdrp + IPXH_CHECKSUM, allffs, 2);
  794. PUTUSHORT2SHORT(hdrp + IPXH_LENGTH, TIMER_REQUEST_PACKET_LENGTH);
  795. *(hdrp + IPXH_XPORTCTL) = 0;
  796. *(hdrp + IPXH_PKTTYPE) = IPX_PACKET_EXCHANGE_TYPE;
  797. memcpy(hdrp + IPXH_DESTNET, allzeros, 4);
  798. memcpy(hdrp + IPXH_DESTNODE, allffs, 6);
  799. PUTUSHORT2SHORT(hdrp + IPXH_DESTSOCK, IPXWAN_SOCKET);
  800. memcpy(hdrp + IPXH_SRCNET, allzeros, 4);
  801. memcpy(hdrp + IPXH_SRCNODE, allzeros, 6);
  802. PUTUSHORT2SHORT(hdrp + IPXH_DESTSOCK, IPXWAN_SOCKET);
  803. // set IPXWAN Header
  804. ipxwanhdrp = hdrp + IPXH_HDRSIZE;
  805. *(ipxwanhdrp + WPACKET_TYPE) = TIMER_RESPONSE;
  806. GETLONG2ULONG(&RemoteWNodeId, ipxwanhdrp + WNODE_ID);
  807. memcpy(ipxwanhdrp + WNODE_ID, acbp->InternalNetNumber, 4);
  808. // parse each option in the received timer request packet
  809. for(optp = ipxwanhdrp + IPXWAN_HDRSIZE, i=0;
  810. i < *(ipxwanhdrp + WNUM_OPTIONS);
  811. i++, optp += OPTION_HDRSIZE + optlen)
  812. {
  813. GETSHORT2USHORT(&optlen, optp + WOPTION_DATA_LEN);
  814. switch(*(optp + WOPTION_NUMBER)) {
  815. case ROUTING_TYPE_OPTION:
  816. if(optlen != ROUTING_TYPE_DATA_LEN) {
  817. return ERROR_GENERATE_NAK;
  818. }
  819. if((*(optp + WOPTION_DATA) == WORKSTATION_ROUTING_TYPE) &&
  820. (IS_WORKSTATION(acbp->SupportedRoutingTypes)) &&
  821. (acbp->RoutingType == 0) &&
  822. (*(optp + WACCEPT_OPTION) == YES)) {
  823. SET_WORKSTATION(acbp->RoutingType);
  824. Trace(IPXWAN_TRACE, "MakeTimerResponsePacket: adapter # %d, accept routing type: %s",
  825. acbp->AdapterIndex,
  826. Workstationp);
  827. }
  828. else if((*(optp + WOPTION_DATA) == UNNUMBERED_RIP_ROUTING_TYPE) &&
  829. (IS_UNNUMBERED_RIP(acbp->SupportedRoutingTypes)) &&
  830. (acbp->RoutingType == 0) &&
  831. (*(optp + WACCEPT_OPTION) == YES)) {
  832. SET_UNNUMBERED_RIP(acbp->RoutingType);
  833. Trace(IPXWAN_TRACE, "MakeTimerResponsePacket: adapter # %d, accept routing type: %s",
  834. acbp->AdapterIndex,
  835. UnnumberedRip);
  836. }
  837. else if((*(optp + WOPTION_DATA) == NUMBERED_RIP_ROUTING_TYPE) &&
  838. (acbp->RoutingType == 0) &&
  839. (*(optp + WACCEPT_OPTION) == YES)) {
  840. if(IS_NUMBERED_RIP(acbp->SupportedRoutingTypes)) {
  841. SET_NUMBERED_RIP(acbp->RoutingType);
  842. Trace(IPXWAN_TRACE, "MakeTimerResponsePacket: adapter # %d, accept routing type: %s",
  843. acbp->AdapterIndex,
  844. NumberedRip);
  845. }
  846. else if((IS_UNNUMBERED_RIP(acbp->SupportedRoutingTypes)) &&
  847. RemoteWNodeId) {
  848. // the local router cannot assign net numbers but it
  849. // accepts the numbered rip type because the remote router
  850. // claims it can assign a net number (because remote node id is not null).
  851. SET_NUMBERED_RIP(acbp->RoutingType);
  852. Trace(IPXWAN_TRACE, "MakeTimerResponsePacket: adapter # %d, accept routing type: %s",
  853. acbp->AdapterIndex,
  854. NumberedRip);
  855. }
  856. else
  857. {
  858. *(optp + WACCEPT_OPTION) = NO;
  859. Trace(IPXWAN_TRACE, "MakeTimerResponsePacket: adapter # %d, decline routing type: %d",
  860. acbp->AdapterIndex,
  861. *(optp + WOPTION_NUMBER));
  862. }
  863. }
  864. else
  865. {
  866. *(optp + WACCEPT_OPTION) = NO;
  867. Trace(IPXWAN_TRACE, "MakeTimerResponsePacket: adapter # %d, decline routing type: %d",
  868. acbp->AdapterIndex,
  869. *(optp + WOPTION_DATA));
  870. }
  871. break;
  872. case EXTENDED_NODE_ID_OPTION:
  873. if(optlen != EXTENDED_NODE_ID_DATA_LEN) {
  874. return ERROR_GENERATE_NAK;
  875. }
  876. *(optp + WACCEPT_OPTION) = YES;
  877. Trace(IPXWAN_TRACE, "MakeTimerResponsePacket: adapter # %d, accept extended node id",
  878. acbp->AdapterIndex);
  879. break;
  880. case PAD_OPTION:
  881. *(optp + WACCEPT_OPTION) = YES;
  882. Trace(IPXWAN_TRACE, "MakeTimerResponsePacket: adapter # %d, accept padding",
  883. acbp->AdapterIndex);
  884. break;
  885. default:
  886. *(optp + WACCEPT_OPTION) = NO;
  887. Trace(IPXWAN_TRACE, "MakeTimerResponsePacket: adapter # %d, decline option number %d",
  888. acbp->AdapterIndex,
  889. *(optp + WOPTION_NUMBER));
  890. break;
  891. }
  892. }
  893. // check if we have agreed on a routing type
  894. if(!acbp->RoutingType) {
  895. Trace(IPXWAN_TRACE, "MakeTimerResponsePacket: adapter # %d, negotiation failed: no routing type accepted",
  896. acbp->AdapterIndex);
  897. return ERROR_DISCONNECT;
  898. }
  899. return NO_ERROR;
  900. }
  901. /*++
  902. Function: MakeInformationRequestPacket
  903. Descr:
  904. Arguments: acbp - ptr to adapter CB
  905. rcvhdrp - ptr to the received TIMER_RESPONSE packet
  906. hdrp - ptr to the new packet to be made
  907. --*/
  908. DWORD
  909. MakeInformationRequestPacket(PACB acbp,
  910. PUCHAR rcvhdrp,
  911. PUCHAR hdrp)
  912. {
  913. PUCHAR optp;
  914. USHORT optlen;
  915. PUCHAR rcvipxwanhdrp, ipxwanhdrp;
  916. ULONG rt_options_count = 0;
  917. USHORT pktlen = 0;
  918. ULONG i;
  919. ULONG ComputerNameLen;
  920. CHAR ComputerName[49];
  921. memset(ComputerName, 0, 49);
  922. Trace(IPXWAN_TRACE, "MakeInformationRequestPacket: Entered for adpt# %d", acbp->AdapterIndex);
  923. rcvipxwanhdrp = rcvhdrp + IPXH_HDRSIZE;
  924. // establish the routing type
  925. for(optp = rcvipxwanhdrp + IPXWAN_HDRSIZE, i=0;
  926. i < *(rcvipxwanhdrp + WNUM_OPTIONS);
  927. i++, optp += OPTION_HDRSIZE + optlen)
  928. {
  929. GETSHORT2USHORT(&optlen, optp + WOPTION_DATA_LEN);
  930. if(*(optp + WOPTION_NUMBER) == ROUTING_TYPE_OPTION) {
  931. rt_options_count++;
  932. if(optlen != ROUTING_TYPE_DATA_LEN) {
  933. Trace(IPXWAN_TRACE, "MakeInformationRequestPacket: Invalid ROUTING TYPE data len, make NAK for adpt# %d", acbp->AdapterIndex);
  934. return ERROR_GENERATE_NAK;
  935. }
  936. if((*(optp + WOPTION_DATA) == WORKSTATION_ROUTING_TYPE) &&
  937. (IS_WORKSTATION(acbp->SupportedRoutingTypes)) &&
  938. (acbp->RoutingType == 0) &&
  939. (*(optp + WACCEPT_OPTION) == YES)) {
  940. SET_WORKSTATION(acbp->RoutingType);
  941. Trace(IPXWAN_TRACE, "MakeInformationRequestPacket: adpt# %d, accept routing type: %s",
  942. acbp->AdapterIndex,
  943. Workstationp);
  944. }
  945. else if((*(optp + WOPTION_DATA) == UNNUMBERED_RIP_ROUTING_TYPE) &&
  946. (IS_UNNUMBERED_RIP(acbp->SupportedRoutingTypes)) &&
  947. (acbp->RoutingType == 0) &&
  948. (*(optp + WACCEPT_OPTION) == YES)) {
  949. SET_UNNUMBERED_RIP(acbp->RoutingType);
  950. Trace(IPXWAN_TRACE, "MakeInformationRequestPacket: adpt# %d, accept routing type: %s",
  951. acbp->AdapterIndex,
  952. UnnumberedRip);
  953. }
  954. else if((*(optp + WOPTION_DATA) == NUMBERED_RIP_ROUTING_TYPE) &&
  955. (acbp->RoutingType == 0) &&
  956. (IS_NUMBERED_RIP(acbp->SupportedRoutingTypes)) &&
  957. (*(optp + WACCEPT_OPTION) == YES)) {
  958. SET_NUMBERED_RIP(acbp->RoutingType);
  959. Trace(IPXWAN_TRACE, "MakeInformationRequestPacket: adpt# %d, accept routing type: %s",
  960. acbp->AdapterIndex,
  961. NumberedRip);
  962. }
  963. }
  964. }
  965. // there should be one and only one routing type option in the timer response
  966. if(rt_options_count != 1) {
  967. Trace(IPXWAN_TRACE, "MakeInformationRequestPacket: adpt# %d negotiation failed, no/too many routing options",
  968. acbp->AdapterIndex);
  969. return ERROR_DISCONNECT;
  970. }
  971. //
  972. //*** MASTER: Set the common network number and the local node number ***
  973. //
  974. if(IS_UNNUMBERED_RIP(acbp->RoutingType)) {
  975. memset(acbp->Network, 0, 4);
  976. }
  977. else
  978. {
  979. // call ipxcp to get a net number
  980. if(IpxcpGetWanNetNumber(acbp->Network,
  981. &acbp->AllocatedNetworkIndex,
  982. acbp->InterfaceType) != NO_ERROR) {
  983. Trace(IPXWAN_TRACE, "MakeInformationRequestPacket: adpt# %d negotiation failed, cannot allocate net number",
  984. acbp->AdapterIndex);
  985. return ERROR_DISCONNECT;
  986. }
  987. }
  988. memset(acbp->LocalNode, 0, 6);
  989. memcpy(acbp->LocalNode, acbp->InternalNetNumber, 4);
  990. // set IPX Header
  991. pktlen = IPXH_HDRSIZE + IPXWAN_HDRSIZE + OPTION_HDRSIZE + RIP_SAP_INFO_EXCHANGE_DATA_LEN;
  992. memcpy(hdrp + IPXH_CHECKSUM, allffs, 2);
  993. *(hdrp + IPXH_XPORTCTL) = 0;
  994. *(hdrp + IPXH_PKTTYPE) = IPX_PACKET_EXCHANGE_TYPE;
  995. memcpy(hdrp + IPXH_DESTNET, allzeros, 4);
  996. memcpy(hdrp + IPXH_DESTNODE, allffs, 6);
  997. PUTUSHORT2SHORT(hdrp + IPXH_DESTSOCK, IPXWAN_SOCKET);
  998. memcpy(hdrp + IPXH_SRCNET, allzeros, 4);
  999. memcpy(hdrp + IPXH_SRCNODE, allzeros, 6);
  1000. PUTUSHORT2SHORT(hdrp + IPXH_DESTSOCK, IPXWAN_SOCKET);
  1001. // set IPXWAN Header
  1002. ipxwanhdrp = hdrp + IPXH_HDRSIZE;
  1003. memcpy(ipxwanhdrp + WIDENTIFIER, IPXWAN_CONFIDENCE_ID, 4);
  1004. *(ipxwanhdrp + WPACKET_TYPE) = INFORMATION_REQUEST;
  1005. memcpy(ipxwanhdrp + WNODE_ID, acbp->InternalNetNumber, 4);
  1006. // the sequence number is written when the packet gets sent
  1007. *(ipxwanhdrp + WNUM_OPTIONS) = 1;
  1008. // set OPTIONS
  1009. optp = ipxwanhdrp + IPXWAN_HDRSIZE;
  1010. *(optp + WOPTION_NUMBER) = RIP_SAP_INFO_EXCHANGE_OPTION;
  1011. *(optp + WACCEPT_OPTION) = YES;
  1012. PUTUSHORT2SHORT(optp + WOPTION_DATA_LEN, RIP_SAP_INFO_EXCHANGE_DATA_LEN);
  1013. PUTUSHORT2SHORT(optp + WAN_LINK_DELAY, acbp->LinkDelay);
  1014. memcpy(optp + COMMON_NETWORK_NUMBER, acbp->Network, 4);
  1015. memset(optp + ROUTER_NAME, 0, 48);
  1016. ComputerNameLen = 48;
  1017. if(!GetComputerName(optp + ROUTER_NAME,
  1018. &ComputerNameLen)) {
  1019. // failed to get machine name
  1020. return ERROR_DISCONNECT;
  1021. }
  1022. memcpy(ComputerName, optp + ROUTER_NAME, ComputerNameLen);
  1023. Trace(IPXWAN_TRACE, "MakeInformationRequestPacket: adpt# %d, Delay %d\nCommon Net %.2x%.2x%.2x%.2x\nRouterName: %s\n",
  1024. acbp->AdapterIndex,
  1025. acbp->LinkDelay,
  1026. acbp->Network[0],
  1027. acbp->Network[1],
  1028. acbp->Network[2],
  1029. acbp->Network[3],
  1030. ComputerName);
  1031. //
  1032. //*** MASTER: Set the remote node number ***
  1033. //
  1034. if(acbp->InterfaceType == IF_TYPE_WAN_WORKSTATION) {
  1035. // if the remote machine is a connecting wksta we should provide it with a node
  1036. // number
  1037. pktlen += OPTION_HDRSIZE + NODE_NUMBER_DATA_LEN;
  1038. (*(ipxwanhdrp + WNUM_OPTIONS))++;
  1039. optp += OPTION_HDRSIZE + RIP_SAP_INFO_EXCHANGE_DATA_LEN;
  1040. *(optp + WOPTION_NUMBER) = NODE_NUMBER_OPTION;
  1041. *(optp + WACCEPT_OPTION) = YES;
  1042. PUTUSHORT2SHORT(optp + WOPTION_DATA_LEN, NODE_NUMBER_DATA_LEN);
  1043. if(IpxcpGetRemoteNode(acbp->ConnectionId, optp + WOPTION_DATA) != NO_ERROR) {
  1044. return ERROR_DISCONNECT;
  1045. }
  1046. memcpy(acbp->RemoteNode, optp + WOPTION_DATA, 6);
  1047. Trace(IPXWAN_TRACE, "MakeInformationRequestPacket: adpt# %d add NIC Address Option: %.2x%.2x%.2x%.2x%.2x%.2x\n",
  1048. acbp->RemoteNode[0],
  1049. acbp->RemoteNode[1],
  1050. acbp->RemoteNode[2],
  1051. acbp->RemoteNode[3],
  1052. acbp->RemoteNode[4],
  1053. acbp->RemoteNode[5]);
  1054. }
  1055. else
  1056. {
  1057. // remote machine is a router -> its node number is derived from its internal net
  1058. memset(acbp->RemoteNode, 0, 6);
  1059. memcpy(acbp->RemoteNode, rcvipxwanhdrp + WNODE_ID, 4);
  1060. }
  1061. PUTUSHORT2SHORT(hdrp + IPXH_LENGTH, pktlen);
  1062. return NO_ERROR;
  1063. }
  1064. /*++
  1065. Function: MakeInformationResponsePacket
  1066. Descr:
  1067. Arguments: acbp - ptr to adapter CB
  1068. rcvhdrp - ptr to the received INFORMATION_REQUEST packet
  1069. hdrp - ptr to the new packet to be made
  1070. --*/
  1071. DWORD
  1072. MakeInformationResponsePacket(PACB acbp,
  1073. PUCHAR rcvhdrp,
  1074. PUCHAR hdrp)
  1075. {
  1076. USHORT rcvlen;
  1077. USHORT optlen;
  1078. PUCHAR ipxwanhdrp;
  1079. PUCHAR optp;
  1080. UCHAR RcvWNodeId[4];
  1081. ULONG RipSapExchangeOptionCount = 0;
  1082. ULONG NodeNumberOptionCount = 0;
  1083. UCHAR LocalNode[6];
  1084. ULONG i;
  1085. ULONG ComputerNameLen=48;
  1086. Trace(IPXWAN_TRACE, "MakeInformationResponsePacket: Entered adpt# %d", acbp->AdapterIndex);
  1087. memset(LocalNode, 0, 6);
  1088. // get received packet length
  1089. GETSHORT2USHORT(&rcvlen, rcvhdrp + IPXH_LENGTH);
  1090. if(rcvlen < IPXH_HDRSIZE + IPXWAN_HDRSIZE + OPTION_HDRSIZE + RIP_SAP_INFO_EXCHANGE_DATA_LEN) {
  1091. // malformed packet
  1092. return ERROR_IGNORE_PACKET;
  1093. }
  1094. memcpy(hdrp, rcvhdrp, rcvlen);
  1095. // set IPX Header
  1096. memcpy(hdrp + IPXH_CHECKSUM, allffs, 2);
  1097. *(hdrp + IPXH_XPORTCTL) = 0;
  1098. *(hdrp + IPXH_PKTTYPE) = IPX_PACKET_EXCHANGE_TYPE;
  1099. memcpy(hdrp + IPXH_DESTNET, allzeros, 4);
  1100. memcpy(hdrp + IPXH_DESTNODE, allffs, 6);
  1101. PUTUSHORT2SHORT(hdrp + IPXH_DESTSOCK, IPXWAN_SOCKET);
  1102. memcpy(hdrp + IPXH_SRCNET, allzeros, 4);
  1103. memcpy(hdrp + IPXH_SRCNODE, allzeros, 6);
  1104. PUTUSHORT2SHORT(hdrp + IPXH_DESTSOCK, IPXWAN_SOCKET);
  1105. // set IPXWAN Header
  1106. ipxwanhdrp = hdrp + IPXH_HDRSIZE;
  1107. *(ipxwanhdrp + WPACKET_TYPE) = INFORMATION_RESPONSE;
  1108. memcpy(RcvWNodeId, ipxwanhdrp + WNODE_ID, 4);
  1109. memcpy(ipxwanhdrp + WNODE_ID, acbp->InternalNetNumber, 4);
  1110. // parse each option in the received information request packet
  1111. for(optp = ipxwanhdrp + IPXWAN_HDRSIZE, i=0;
  1112. i < *(ipxwanhdrp + WNUM_OPTIONS);
  1113. i++, optp += OPTION_HDRSIZE + optlen)
  1114. {
  1115. GETSHORT2USHORT(&optlen, optp + WOPTION_DATA_LEN);
  1116. switch(*(optp + WOPTION_NUMBER)) {
  1117. case RIP_SAP_INFO_EXCHANGE_OPTION:
  1118. if(RipSapExchangeOptionCount++) {
  1119. // more then one rip/sap exchange option
  1120. Trace(IPXWAN_TRACE, "MakeInformationResponsePacket: adpt# %d, ERROR: more then 1 RIP_SAP_EXCHANGE_OPTION in rcvd INFORAMTION_REQUEST\n",
  1121. acbp->AdapterIndex);
  1122. return ERROR_DISCONNECT;
  1123. }
  1124. if(optlen != RIP_SAP_INFO_EXCHANGE_DATA_LEN) {
  1125. Trace(IPXWAN_TRACE, "MakeInformationResponsePacket: adpt# %d, ERROR: bad length RIP_SAP_EXCHANGE_OPTION in rcvd INFORAMTION_REQUEST\n",
  1126. acbp->AdapterIndex);
  1127. return ERROR_GENERATE_NAK;
  1128. }
  1129. if(*(optp + WACCEPT_OPTION) != YES) {
  1130. Trace(IPXWAN_TRACE, "MakeInformationResponsePacket: adpt# %d, ERROR: ACCEPT==NO RIP_SAP_EXCHANGE_OPTION in rcvd INFORAMTION_REQUEST\n",
  1131. acbp->AdapterIndex);
  1132. return ERROR_DISCONNECT;
  1133. }
  1134. GETSHORT2USHORT(&acbp->LinkDelay, optp + WAN_LINK_DELAY);
  1135. // validate routing type and common net number
  1136. if((IS_NUMBERED_RIP(acbp->RoutingType)) &&
  1137. !memcmp(optp + COMMON_NETWORK_NUMBER, allzeros, 4)) {
  1138. // negotiation error
  1139. Trace(IPXWAN_TRACE, "MakeInformationResponsePacket: adpt# %d, ERROR: NUMBERED RIP Routing but Network==0 in rcvd INFORAMTION_REQUEST\n",
  1140. acbp->AdapterIndex);
  1141. return ERROR_DISCONNECT;
  1142. }
  1143. if((IS_UNNUMBERED_RIP(acbp->RoutingType)) &&
  1144. memcmp(optp + COMMON_NETWORK_NUMBER, allzeros, 4)) {
  1145. // negotiation error
  1146. Trace(IPXWAN_TRACE, "MakeInformationResponsePacket: adpt# %d, ERROR: ON DEMAND Routing but Network!=0 in rcvd INFORAMTION_REQUEST\n",
  1147. acbp->AdapterIndex);
  1148. return ERROR_DISCONNECT;
  1149. }
  1150. // check we were handed a unique net number
  1151. if(memcmp(optp + COMMON_NETWORK_NUMBER, allzeros, 4)) {
  1152. switch(acbp->InterfaceType) {
  1153. case IF_TYPE_WAN_ROUTER:
  1154. case IF_TYPE_PERSONAL_WAN_ROUTER:
  1155. case IF_TYPE_ROUTER_WORKSTATION_DIALOUT:
  1156. if(IpxcpIsRoute(optp + COMMON_NETWORK_NUMBER)) {
  1157. Trace(IPXWAN_TRACE, "MakeInformationResponsePacket: adpt# %d, ERROR: Network not unique in rcvd INFORAMTION_REQUEST\n",
  1158. acbp->AdapterIndex);
  1159. return ERROR_DISCONNECT;
  1160. }
  1161. break;
  1162. default:
  1163. break;
  1164. }
  1165. }
  1166. //
  1167. //*** SLAVE: Set the common net number and the remote node ***
  1168. //
  1169. memcpy(acbp->Network, optp + COMMON_NETWORK_NUMBER, 4);
  1170. Trace(IPXWAN_TRACE, "MakeInformationResponsePacket: adpt# %d, Recvd Common Network Number %.2x%.2x%.2x%.2x\n",
  1171. acbp->AdapterIndex,
  1172. acbp->Network[0],
  1173. acbp->Network[1],
  1174. acbp->Network[2],
  1175. acbp->Network[3]);
  1176. // make the remote node number from its remote WNODE ID field
  1177. memset(acbp->RemoteNode, 0, 6);
  1178. memcpy(acbp->RemoteNode, RcvWNodeId, 4);
  1179. // give our router name
  1180. memset(optp + ROUTER_NAME, 0, 48);
  1181. if(!GetComputerName(optp + ROUTER_NAME, &ComputerNameLen)) {
  1182. // failed to get machine name
  1183. return ERROR_DISCONNECT;
  1184. }
  1185. break;
  1186. case NODE_NUMBER_OPTION:
  1187. if(NodeNumberOptionCount++) {
  1188. Trace(IPXWAN_TRACE, "MakeInformationResponsePacket: adpt# %d, ERROR: more than 1 NODE_NUMBER_OPTION in rcvd INFORMATION_REQUEST\n",
  1189. acbp->AdapterIndex);
  1190. return ERROR_DISCONNECT;
  1191. }
  1192. if(optlen != NODE_NUMBER_DATA_LEN) {
  1193. Trace(IPXWAN_TRACE, "MakeInformationResponsePacket: adpt# %d, ERROR: bad length for NODE_NUMBER_OPTION in rcvd INFORMATION_REQUEST\n",
  1194. acbp->AdapterIndex);
  1195. return ERROR_GENERATE_NAK;
  1196. }
  1197. if(*(optp + WACCEPT_OPTION) != YES) {
  1198. Trace(IPXWAN_TRACE, "MakeInformationResponsePacket: adpt# %d, ERROR: ACCEPT==NO for NODE_NUMBER_OPTION in rcvd INFORMATION_REQUEST\n",
  1199. acbp->AdapterIndex);
  1200. return ERROR_DISCONNECT;
  1201. }
  1202. memcpy(LocalNode, optp + WOPTION_DATA, 6);
  1203. break;
  1204. default:
  1205. *(optp + WACCEPT_OPTION) = NO;
  1206. break;
  1207. }
  1208. }
  1209. //
  1210. //*** SLAVE: Set local node ***
  1211. //
  1212. if(NodeNumberOptionCount) {
  1213. memcpy(acbp->LocalNode, LocalNode, 6);
  1214. }
  1215. else
  1216. {
  1217. // make the local node from our internal net
  1218. memset(acbp->LocalNode, 0, 6);
  1219. memcpy(acbp->LocalNode, acbp->InternalNetNumber, 4);
  1220. }
  1221. return NO_ERROR;
  1222. }
  1223. /*++
  1224. Function: MakeNakPacket
  1225. Descr:
  1226. Arguments: acbp - ptr to adapter CB
  1227. rcvhdrp - ptr to the received UNKNOWN packet
  1228. hdrp - ptr to the new packet to be made
  1229. --*/
  1230. DWORD
  1231. MakeNakPacket(PACB acbp,
  1232. PUCHAR rcvhdrp,
  1233. PUCHAR hdrp)
  1234. {
  1235. USHORT rcvlen;
  1236. PUCHAR ipxwanhdrp;
  1237. // get received packet length
  1238. GETSHORT2USHORT(&rcvlen, rcvhdrp + IPXH_LENGTH);
  1239. memcpy(hdrp, rcvhdrp, rcvlen);
  1240. // set IPXWAN Header
  1241. ipxwanhdrp = hdrp + IPXH_HDRSIZE;
  1242. *(ipxwanhdrp + WPACKET_TYPE) = NAK;
  1243. return NO_ERROR;
  1244. }
  1245. /*++
  1246. Function: ProcessInformationResponsePacket
  1247. Descr:
  1248. Arguments: acbp - ptr to adapter CB
  1249. rcvhdrp - ptr to the received INFORMATION_RESPONSE packet
  1250. --*/
  1251. DWORD
  1252. ProcessInformationResponsePacket(PACB acbp,
  1253. PUCHAR rcvhdrp)
  1254. {
  1255. USHORT rcvlen;
  1256. USHORT optlen;
  1257. PUCHAR ipxwanhdrp;
  1258. PUCHAR optp;
  1259. ULONG RipSapExchangeOptionCount = 0;
  1260. ULONG i;
  1261. Trace(IPXWAN_TRACE, "ProcessInformationResponsePacket: Entered adpt# %d", acbp->AdapterIndex);
  1262. // get received packet length
  1263. GETSHORT2USHORT(&rcvlen, rcvhdrp + IPXH_LENGTH);
  1264. if(rcvlen < IPXH_HDRSIZE + IPXWAN_HDRSIZE + OPTION_HDRSIZE + RIP_SAP_INFO_EXCHANGE_DATA_LEN) {
  1265. // malformed packet
  1266. return ERROR_IGNORE_PACKET;
  1267. }
  1268. ipxwanhdrp =rcvhdrp + IPXH_HDRSIZE;
  1269. // parse each option in the received information response packet
  1270. for(optp = ipxwanhdrp + IPXWAN_HDRSIZE, i=0;
  1271. i < *(ipxwanhdrp + WNUM_OPTIONS);
  1272. i++, optp += OPTION_HDRSIZE + optlen)
  1273. {
  1274. GETSHORT2USHORT(&optlen, optp + WOPTION_DATA_LEN);
  1275. switch(*(optp + WOPTION_NUMBER)) {
  1276. case RIP_SAP_INFO_EXCHANGE_OPTION:
  1277. if(RipSapExchangeOptionCount++) {
  1278. // more then one rip/sap exchange option
  1279. Trace(IPXWAN_TRACE, "ProcessInformationResponsePacket: adpt# %d, ERROR: more then 1 RIP_SAP_INFO_EXCHANGE_OPTION in rcvd INFORMATION_RESPONSE\n",
  1280. acbp->AdapterIndex);
  1281. return ERROR_DISCONNECT;
  1282. }
  1283. if(optlen != RIP_SAP_INFO_EXCHANGE_DATA_LEN) {
  1284. Trace(IPXWAN_TRACE, "ProcessInformationResponsePacket: adpt# %d, ERROR: bad length RIP_SAP_EXCHANGE_OPTION in rcvd INFORMATION_RESPONSE\n",
  1285. acbp->AdapterIndex);
  1286. return ERROR_GENERATE_NAK;
  1287. }
  1288. if(*(optp + WACCEPT_OPTION) != YES) {
  1289. Trace(IPXWAN_TRACE, "ProcessInformationResponsePacket: adpt# %d, ERROR: ACCEPT==NO RIP_SAP_EXCHANGE_OPTION in rcvd INFORMATION_RESPONSE\n",
  1290. acbp->AdapterIndex);
  1291. return ERROR_DISCONNECT;
  1292. }
  1293. if(memcmp(optp + COMMON_NETWORK_NUMBER, acbp->Network, 4)) {
  1294. // we don't agree on the common net number
  1295. Trace(IPXWAN_TRACE, "ProcessInformationResponsePacket: adpt# %d, ERROR: Different common net returned\n",
  1296. acbp->AdapterIndex);
  1297. return ERROR_DISCONNECT;
  1298. }
  1299. break;
  1300. case NODE_NUMBER_OPTION:
  1301. if(optlen != NODE_NUMBER_DATA_LEN) {
  1302. Trace(IPXWAN_TRACE, "ProcessInformationResponsePacket: adpt# %d, ERROR: bad length NODE_NUMBER_OPTION in rcvd INFORMATION_REQUEST\n",
  1303. acbp->AdapterIndex);
  1304. return ERROR_GENERATE_NAK;
  1305. }
  1306. if(*(optp + WACCEPT_OPTION) != YES) {
  1307. Trace(IPXWAN_TRACE, "ProcessInformationResponsePacket: adpt# %d, ERROR: ACCEPT==NO NODE_NUMBER_OPTION in rcvd INFORMATION_RESPONSE\n",
  1308. acbp->AdapterIndex);
  1309. return ERROR_DISCONNECT;
  1310. }
  1311. // check that it coincides with the number we assigned
  1312. if(memcmp(optp + WOPTION_DATA, acbp->RemoteNode, 6)) {
  1313. Trace(IPXWAN_TRACE, "ProcessInformationResponsePacket: adpt# %d, ERROR: Different remote node number returned\n",
  1314. acbp->AdapterIndex);
  1315. return ERROR_DISCONNECT;
  1316. }
  1317. break;
  1318. default:
  1319. Trace(IPXWAN_TRACE, "ProcessInformationResponsePacket: adpt# %d, ERROR: Unrequested option in rcvd INFORMATION_RESPONSE\n",
  1320. acbp->AdapterIndex);
  1321. return ERROR_DISCONNECT;
  1322. break;
  1323. }
  1324. }
  1325. if(!RipSapExchangeOptionCount) {
  1326. Trace(IPXWAN_TRACE, "ProcessInformationResponsePacket: adpt# %d, ERROR: RIP_SAP_EXCHANGE_OPTION missing from rcvd INFORMATION_RESPONSE\n",
  1327. acbp->AdapterIndex);
  1328. return ERROR_DISCONNECT;
  1329. }
  1330. return NO_ERROR;
  1331. }
  1332. VOID
  1333. fillpadding(PUCHAR padp,
  1334. ULONG len)
  1335. {
  1336. ULONG i;
  1337. for(i=0; i<len; i++)
  1338. {
  1339. *(padp + i) = (UCHAR)i;
  1340. }
  1341. }
  1342. /*++
  1343. Function: StartSlaveTimer
  1344. Descr: A timer is started when the slave gets its role (i.e. slave) and sends
  1345. a timer response. This insures the slave won't wait forever to receive
  1346. an information request.
  1347. Remark: >> called with the adapter lock held <<
  1348. --*/
  1349. DWORD
  1350. StartSlaveTimer(PACB acbp)
  1351. {
  1352. PWORK_ITEM wip;
  1353. if((wip = AllocateWorkItem(WITIMER_TYPE)) == NULL) {
  1354. return ERROR_DISCONNECT;
  1355. }
  1356. wip->acbp = acbp;
  1357. StartWiTimer(wip, SLAVE_TIMEOUT);
  1358. acbp->RefCount++;
  1359. return NO_ERROR;
  1360. }