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.

2242 lines
51 KiB

  1. /*++
  2. Copyright (c) 1996 Microsoft Corporation
  3. Module Name:
  4. arppkt.c - ATMARP Packet Routines.
  5. Abstract:
  6. Routines that build and parse ARP packets.
  7. Revision History:
  8. Who When What
  9. -------- -------- ----------------------------------------------
  10. arvindm 07-29-96 Created
  11. Notes:
  12. --*/
  13. #include <precomp.h>
  14. #define _FILENUMBER 'TKPA'
  15. VOID
  16. AtmArpSendPacketOnVc(
  17. IN PATMARP_VC pVc LOCKIN NOLOCKOUT,
  18. IN PNDIS_PACKET pNdisPacket
  19. )
  20. /*++
  21. Routine Description:
  22. Send a packet on the specified VC. Apart from calling NDIS to do
  23. the job, we refresh the aging timer on this VC.
  24. Arguments:
  25. pVc - Pointer to ATMARP VC
  26. pNdisPacket - Pointer to packet to be sent.
  27. Return Value:
  28. None
  29. --*/
  30. {
  31. NDIS_HANDLE NdisVcHandle;
  32. if (AA_IS_FLAG_SET(
  33. pVc->Flags,
  34. AA_VC_CALL_STATE_MASK,
  35. AA_VC_CALL_STATE_ACTIVE) &&
  36. !AA_IS_VC_GOING_DOWN(pVc))
  37. {
  38. //
  39. // A call is active on this VC, so send the packet.
  40. //
  41. AtmArpRefreshTimer(&(pVc->Timer));
  42. NdisVcHandle = pVc->NdisVcHandle;
  43. #ifdef VC_REFS_ON_SENDS
  44. AtmArpReferenceVc(pVc); // SendPacketOnVc
  45. #endif // VC_REFS_ON_SENDS
  46. pVc->OutstandingSends++; // SendPacketOnVc
  47. AA_RELEASE_VC_LOCK(pVc);
  48. AADEBUGP(AAD_EXTRA_LOUD+50,
  49. ("SendPacketOnVc: pVc 0x%x, Pkt 0x%x, VcHandle 0x%x\n",
  50. pVc, pNdisPacket, NdisVcHandle));
  51. #ifdef PERF
  52. AadLogSendUpdate(pNdisPacket);
  53. #endif // PERF
  54. NDIS_CO_SEND_PACKETS(
  55. NdisVcHandle,
  56. &pNdisPacket,
  57. 1
  58. );
  59. }
  60. else
  61. {
  62. if (!AA_IS_VC_GOING_DOWN(pVc))
  63. {
  64. //
  65. // Call must be in progress. Queue this packet; it will
  66. // be sent as soon as the call is fully set up.
  67. //
  68. AtmArpQueuePacketOnVc(pVc, pNdisPacket);
  69. AA_RELEASE_VC_LOCK(pVc);
  70. }
  71. else
  72. {
  73. //
  74. // This VC is going down. Complete the send with a failure.
  75. //
  76. #ifdef VC_REFS_ON_SENDS
  77. AtmArpReferenceVc(pVc); // SendPacketOnVc2
  78. #endif // VC_REFS_ON_SENDS
  79. pVc->OutstandingSends++; // SendPacketOnVc - failure completion
  80. AA_RELEASE_VC_LOCK(pVc);
  81. #if DBG
  82. #if DBG_CO_SEND
  83. {
  84. PULONG pContext;
  85. pContext = (PULONG)&(pNdisPacket->WrapperReserved[0]);;
  86. *pContext = 'AaAa';
  87. }
  88. #endif
  89. #endif
  90. AtmArpCoSendCompleteHandler(
  91. NDIS_STATUS_FAILURE,
  92. (NDIS_HANDLE)pVc,
  93. pNdisPacket
  94. );
  95. }
  96. }
  97. return;
  98. }
  99. PNDIS_PACKET
  100. AtmArpBuildARPPacket(
  101. IN USHORT OperationType,
  102. IN PATMARP_INTERFACE pInterface,
  103. IN PUCHAR * ppArpPacket,
  104. IN PAA_ARP_PKT_CONTENTS pArpContents
  105. )
  106. /*++
  107. Routine Description:
  108. Build a generic ARP packet with the given attributes.
  109. Arguments:
  110. OperationType - Op type (e.g. ARP Request, ARP Reply)
  111. pInterface - Pointer to ATMARP Interface
  112. ppArpPacket - Pointer to place to return start of packet
  113. pArpContents - Pointer to structure describing contents
  114. Return Value:
  115. Pointer to NDIS packet if successful, NULL otherwise. If successful,
  116. we also set *ppArpPacket to point to the first byte in the constructed
  117. ARP packet.
  118. --*/
  119. {
  120. PNDIS_PACKET pNdisPacket;
  121. PNDIS_BUFFER pNdisBuffer;
  122. ULONG BufferLength; // Length of ARP packet
  123. ULONG Length; // Temp length
  124. PUCHAR pPkt; // Start of allocated packet
  125. PUCHAR pBuf; // Used to walk the packet
  126. PAA_ARP_PKT_HEADER pArpHeader; // ARP packet header
  127. //
  128. // Calculate the length of what we're about to build
  129. //
  130. BufferLength = AA_ARP_PKT_HEADER_LENGTH +
  131. (pArpContents->SrcAtmNumberTypeLen & ~AA_PKT_ATM_ADDRESS_BIT) +
  132. (pArpContents->SrcAtmSubaddrTypeLen & ~AA_PKT_ATM_ADDRESS_BIT) +
  133. (pArpContents->DstAtmNumberTypeLen & ~AA_PKT_ATM_ADDRESS_BIT) +
  134. (pArpContents->DstAtmSubaddrTypeLen & ~AA_PKT_ATM_ADDRESS_BIT) +
  135. 0;
  136. if (pArpContents->pSrcIPAddress != (PUCHAR)NULL)
  137. {
  138. BufferLength += AA_IPV4_ADDRESS_LENGTH;
  139. }
  140. if (pArpContents->pDstIPAddress != (PUCHAR)NULL)
  141. {
  142. BufferLength += AA_IPV4_ADDRESS_LENGTH;
  143. }
  144. pNdisPacket = AtmArpAllocatePacket(pInterface);
  145. if (pNdisPacket != (PNDIS_PACKET)NULL)
  146. {
  147. pNdisBuffer = AtmArpAllocateProtoBuffer(
  148. pInterface,
  149. BufferLength,
  150. &(pPkt)
  151. );
  152. if (pNdisBuffer != (PNDIS_BUFFER)NULL)
  153. {
  154. //
  155. // Return value:
  156. //
  157. *ppArpPacket = pPkt;
  158. //
  159. // Initialize packet with all 0's
  160. //
  161. AA_SET_MEM(pPkt, 0, BufferLength);
  162. pArpHeader = (PAA_ARP_PKT_HEADER)pPkt;
  163. //
  164. // Fixed-location fields:
  165. //
  166. pArpHeader->LLCSNAPHeader = AtmArpLlcSnapHeader;
  167. pArpHeader->LLCSNAPHeader.EtherType = NET_SHORT(AA_PKT_ETHERTYPE_ARP);
  168. pArpHeader->hrd = NET_SHORT(AA_PKT_ATM_FORUM_AF);
  169. pArpHeader->pro = NET_SHORT(AA_PKT_PRO_IP);
  170. pArpHeader->op = NET_SHORT(OperationType);
  171. //
  172. // Now fill in the variable length fields
  173. //
  174. pBuf = pArpHeader->Variable;
  175. //
  176. // Source ATM Number
  177. //
  178. Length = (pArpContents->SrcAtmNumberTypeLen & ~AA_PKT_ATM_ADDRESS_BIT);
  179. if (Length > 0)
  180. {
  181. pArpHeader->shtl = pArpContents->SrcAtmNumberTypeLen;
  182. AA_COPY_MEM(pBuf, pArpContents->pSrcAtmNumber, Length);
  183. pBuf += Length;
  184. }
  185. //
  186. // Source ATM subaddress
  187. //
  188. Length = (pArpContents->SrcAtmSubaddrTypeLen & ~AA_PKT_ATM_ADDRESS_BIT);
  189. if (Length > 0)
  190. {
  191. pArpHeader->shtl = pArpContents->SrcAtmSubaddrTypeLen;
  192. AA_COPY_MEM(pBuf, pArpContents->pSrcAtmSubaddress, Length);
  193. pBuf += Length;
  194. }
  195. //
  196. // Source Protocol (IP) address
  197. //
  198. if (pArpContents->pSrcIPAddress != (PUCHAR)NULL)
  199. {
  200. pArpHeader->spln = AA_IPV4_ADDRESS_LENGTH;
  201. AA_COPY_MEM(pBuf, pArpContents->pSrcIPAddress, AA_IPV4_ADDRESS_LENGTH);
  202. pBuf += AA_IPV4_ADDRESS_LENGTH;
  203. }
  204. //
  205. // Target ATM Number
  206. //
  207. Length = (pArpContents->DstAtmNumberTypeLen & ~AA_PKT_ATM_ADDRESS_BIT);
  208. if (Length > 0)
  209. {
  210. pArpHeader->thtl = pArpContents->DstAtmNumberTypeLen;
  211. AA_COPY_MEM(pBuf, pArpContents->pDstAtmNumber, Length);
  212. pBuf += Length;
  213. }
  214. //
  215. // Target ATM subaddress
  216. //
  217. Length = (pArpContents->DstAtmSubaddrTypeLen & ~AA_PKT_ATM_ADDRESS_BIT);
  218. if (Length > 0)
  219. {
  220. pArpHeader->thtl = pArpContents->DstAtmSubaddrTypeLen;
  221. AA_COPY_MEM(pBuf, pArpContents->pDstAtmSubaddress, Length);
  222. pBuf += Length;
  223. }
  224. //
  225. // Target Protocol (IP) address
  226. //
  227. if (pArpContents->pDstIPAddress != (PUCHAR)NULL)
  228. {
  229. pArpHeader->tpln = AA_IPV4_ADDRESS_LENGTH;
  230. AA_COPY_MEM(pBuf, pArpContents->pDstIPAddress, AA_IPV4_ADDRESS_LENGTH);
  231. pBuf += AA_IPV4_ADDRESS_LENGTH;
  232. }
  233. NdisChainBufferAtFront(pNdisPacket, pNdisBuffer);
  234. }
  235. else
  236. {
  237. AtmArpFreePacket(pInterface, pNdisPacket);
  238. pNdisPacket = (PNDIS_PACKET)NULL;
  239. }
  240. }
  241. AADEBUGP(AAD_EXTRA_LOUD, ("BldArpPkt: pIf 0x%x, Op %d, NdisPkt 0x%x, NdisBuf 0x%x\n",
  242. pInterface, OperationType, pNdisPacket, pNdisBuffer));
  243. return (pNdisPacket);
  244. }
  245. VOID
  246. AtmArpSendARPRequest(
  247. PATMARP_INTERFACE pInterface,
  248. IP_ADDRESS UNALIGNED * pSrcIPAddress,
  249. IP_ADDRESS UNALIGNED * pDstIPAddress
  250. )
  251. /*++
  252. Routine Description:
  253. Send an ARP Request to the server, for the given interface.
  254. Preconditions: the ATM interface is UP, and the AdminState
  255. for the interface is IF_STATUS_UP.
  256. We first build an ARP Request with the given parameters. Then,
  257. if a Best Effort VC to the server's ATM address exists, the packet
  258. is sent on this. Other possibilities:
  259. - the Best Effort VC to the server is being set up: queue it
  260. on the VC
  261. - No Best Effort VC to the server exists: Create a new VC on this
  262. ATM Entry, make a call with Best Effort flow specs, and queue
  263. the request on this VC.
  264. Arguments:
  265. pInterface - Pointer to ATMARP Interface structure
  266. pSrcIPAddress - Pointer to Source IP Address
  267. pDstIPAddress - Pointer to Destination IP Address (to be
  268. resolved)
  269. Return Value:
  270. None
  271. --*/
  272. {
  273. PATMARP_ATM_ENTRY pAtmEntry; // Entry for the server's ATM address
  274. PATMARP_VC pVc; // VC to the server
  275. PNDIS_PACKET pNdisPacket;
  276. PATMARP_FLOW_SPEC pFlowSpec;
  277. PUCHAR pArpPacket; // Pointer to ARP packet being constructed
  278. AA_ARP_PKT_CONTENTS ArpContents;// Describes the packet we want to build
  279. NDIS_STATUS Status;
  280. AADEBUGP(AAD_INFO,
  281. ("Sending ARP Request on IF 0x%x for IP Addr: %d.%d.%d.%d\n",
  282. pInterface,
  283. ((PUCHAR)pDstIPAddress)[0],
  284. ((PUCHAR)pDstIPAddress)[1],
  285. ((PUCHAR)pDstIPAddress)[2],
  286. ((PUCHAR)pDstIPAddress)[3]
  287. ));
  288. AA_ASSERT(pInterface->pCurrentServer != NULL_PATMARP_SERVER_ENTRY);
  289. AA_ASSERT(pInterface->pCurrentServer->pAtmEntry != NULL_PATMARP_ATM_ENTRY);
  290. //
  291. // Prepare the ARP packet contents structure
  292. //
  293. AA_SET_MEM((PUCHAR)&ArpContents, 0, sizeof(AA_ARP_PKT_CONTENTS));
  294. //
  295. // Source ATM Number
  296. //
  297. ArpContents.pSrcAtmNumber = pInterface->LocalAtmAddress.Address;
  298. ArpContents.SrcAtmNumberTypeLen =
  299. AA_PKT_ATM_ADDRESS_TO_TYPE_LEN(&(pInterface->LocalAtmAddress));
  300. //
  301. // Source IP Address
  302. //
  303. ArpContents.pSrcIPAddress = (PUCHAR)pSrcIPAddress;
  304. //
  305. // Target IP Address
  306. //
  307. ArpContents.pDstIPAddress = (PUCHAR)pDstIPAddress;
  308. //
  309. // Build the ARP Request
  310. //
  311. pNdisPacket = AtmArpBuildARPPacket(
  312. AA_PKT_OP_TYPE_ARP_REQUEST,
  313. pInterface,
  314. &pArpPacket,
  315. &ArpContents
  316. );
  317. if (pNdisPacket != (PNDIS_PACKET)NULL)
  318. {
  319. //
  320. // Find the ATM Entry for the in-use ATMARP Server:
  321. //
  322. AA_ACQUIRE_IF_LOCK(pInterface);
  323. pAtmEntry = pInterface->pCurrentServer->pAtmEntry;
  324. AA_RELEASE_IF_LOCK(pInterface);
  325. AA_ACQUIRE_AE_LOCK(pAtmEntry);
  326. //
  327. // Get at the Best Effort VC going to this ATM address:
  328. //
  329. pVc = pAtmEntry->pBestEffortVc;
  330. if (pVc != NULL_PATMARP_VC)
  331. {
  332. ULONG rc;
  333. AA_ACQUIRE_VC_LOCK_DPC(pVc);
  334. AtmArpReferenceVc(pVc); // temp ref
  335. AA_RELEASE_VC_LOCK_DPC(pVc);
  336. AA_RELEASE_AE_LOCK(pAtmEntry); // Not needed anymore
  337. //
  338. // A VC to the server exists; send this packet on the VC
  339. //
  340. AA_ACQUIRE_VC_LOCK(pVc);
  341. rc = AtmArpDereferenceVc(pVc); // temp ref
  342. if (rc != 0)
  343. {
  344. AtmArpSendPacketOnVc(pVc, pNdisPacket);
  345. //
  346. // The VC lock is released in SendPacketOnVc
  347. //
  348. }
  349. else
  350. {
  351. //
  352. // The VC has been deref'ed away! Set up pVc for the
  353. // check coming up.
  354. //
  355. pVc = NULL_PATMARP_VC;
  356. AA_ACQUIRE_AE_LOCK(pAtmEntry);
  357. }
  358. }
  359. if (pVc == NULL_PATMARP_VC)
  360. {
  361. //
  362. // We don't have an appropriate VC to the server, so create
  363. // one, and queue this packet for transmission as soon as
  364. // the call is made.
  365. //
  366. // AtmArpMakeCall needs the caller to hold the ATM Entry lock.
  367. //
  368. AA_GET_CONTROL_PACKET_SPECS(pInterface, &pFlowSpec);
  369. Status = AtmArpMakeCall(
  370. pInterface,
  371. pAtmEntry,
  372. pFlowSpec,
  373. pNdisPacket
  374. );
  375. //
  376. // The AE lock is released within the above.
  377. //
  378. }
  379. }
  380. }
  381. VOID
  382. AtmArpSendInARPRequest(
  383. IN PATMARP_VC pVc
  384. )
  385. /*++
  386. Routine Description:
  387. Send an InATMARP Request on a VC.
  388. Arguments:
  389. pVc - Pointer to ATMARP VC on which we send the request
  390. Return Value:
  391. None
  392. --*/
  393. {
  394. PATMARP_INTERFACE pInterface;
  395. PNDIS_PACKET pNdisPacket;
  396. PUCHAR pArpPacket; // Pointer to ARP packet being constructed
  397. AA_ARP_PKT_CONTENTS ArpContents;// Describes the packet we want to build
  398. //
  399. // Prepare the ARP packet contents structure
  400. //
  401. AA_SET_MEM((PUCHAR)&ArpContents, 0, sizeof(AA_ARP_PKT_CONTENTS));
  402. pInterface = pVc->pInterface;
  403. //
  404. // Source IP Address
  405. //
  406. ArpContents.pSrcIPAddress = (PUCHAR)&(pInterface->LocalIPAddress.IPAddress);
  407. //
  408. // Source ATM number
  409. //
  410. ArpContents.pSrcAtmNumber = pInterface->LocalAtmAddress.Address;
  411. ArpContents.SrcAtmNumberTypeLen =
  412. AA_PKT_ATM_ADDRESS_TO_TYPE_LEN(&(pInterface->LocalAtmAddress));
  413. //
  414. // Build the InATMARP Request packet
  415. //
  416. pNdisPacket = AtmArpBuildARPPacket(
  417. AA_PKT_OP_TYPE_INARP_REQUEST,
  418. pInterface,
  419. &pArpPacket,
  420. &ArpContents
  421. );
  422. if (pNdisPacket != (PNDIS_PACKET)NULL)
  423. {
  424. #ifndef VC_REFS_ON_SENDS
  425. AA_ACQUIRE_VC_LOCK(pVc);
  426. #endif // VC_REFS_ON_SENDS
  427. AtmArpSendPacketOnVc(pVc, pNdisPacket);
  428. //
  429. // The VC lock is released by SendPacketOnVc
  430. //
  431. }
  432. else
  433. {
  434. #ifdef VC_REFS_ON_SENDS
  435. AA_RELEASE_VC_LOCK(pVc);
  436. #endif // VC_REFS_ON_SENDS
  437. }
  438. }
  439. UINT
  440. AtmArpCoReceivePacketHandler(
  441. IN NDIS_HANDLE ProtocolBindingContext,
  442. IN NDIS_HANDLE ProtocolVcContext,
  443. IN PNDIS_PACKET pNdisPacket
  444. )
  445. /*++
  446. Routine Description:
  447. This is routine is called when a packet is received on a VC owned
  448. by the ATMARP module. If it is an ARP packet, we consume it ourselves.
  449. Otherwise, we pass it up to IP.
  450. In any case, we refresh the VC aging timer on this VC.
  451. Arguments:
  452. ProtocolBindingContext - Actually a pointer to our Adapter structure
  453. ProtocolVcContext - Actually a pointer to our VC structure
  454. pNdisPacket - NDIS packet being received.
  455. Return Value:
  456. 0 always, because we don't hold on to ARP packets, and we assume
  457. IP doesn't either.
  458. --*/
  459. {
  460. PATMARP_INTERFACE pInterface;
  461. PATMARP_VC pVc;
  462. UINT TotalLength; // Total bytes in packet
  463. PNDIS_BUFFER pNdisBuffer; // Pointer to first buffer
  464. UINT BufferLength;
  465. UINT IsNonUnicast; // Is this to a non-unicast destn MAC addr?
  466. BOOLEAN Discarded; // Are we discarding this packet?
  467. PAA_PKT_LLC_SNAP_HEADER pPktHeader; // LLC/SNAP header
  468. UINT ReturnCount = 0;
  469. #if DBG
  470. pPktHeader = NULL;
  471. #endif
  472. pVc = (PATMARP_VC)ProtocolVcContext;
  473. AA_STRUCT_ASSERT(pVc, avc);
  474. pInterface = pVc->pInterface;
  475. Discarded = FALSE;
  476. IsNonUnicast = (UINT)FALSE;
  477. if (pInterface->AdminState == IF_STATUS_UP)
  478. {
  479. //
  480. // Refresh VC aging on this VC
  481. //
  482. AA_ACQUIRE_VC_LOCK(pVc);
  483. AtmArpRefreshTimer(&(pVc->Timer));
  484. AA_RELEASE_VC_LOCK(pVc);
  485. NdisQueryPacket(
  486. pNdisPacket,
  487. NULL,
  488. NULL,
  489. &pNdisBuffer,
  490. &TotalLength
  491. );
  492. //
  493. // We expect atleast the LLC/SNAP header to be present
  494. // Note: this precludes Null encapsulation.
  495. //
  496. if (TotalLength >= AA_PKT_LLC_SNAP_HEADER_LENGTH)
  497. {
  498. AA_IF_STAT_ADD(pInterface, InOctets, TotalLength);
  499. NdisQueryBuffer(
  500. pNdisBuffer,
  501. (PVOID *)&pPktHeader,
  502. &BufferLength
  503. );
  504. AADEBUGP(AAD_EXTRA_LOUD,
  505. ("Rcv: VC 0x%x, NDISpkt 0x%x, NDISbuf 0x%x, Buflen %d, Totlen %d, Pkthdr 0x%x\n",
  506. pVc,
  507. pNdisPacket,
  508. pNdisBuffer,
  509. BufferLength,
  510. TotalLength,
  511. pPktHeader));
  512. AADEBUGPDUMP(AAD_EXTRA_LOUD+20, pPktHeader, BufferLength);
  513. AA_ASSERT(BufferLength >= AA_PKT_LLC_SNAP_HEADER_LENGTH);
  514. if (AA_PKT_LLC_SNAP_HEADER_OK(pPktHeader))
  515. {
  516. //
  517. // If the EtherType is IP, pass up this packet to
  518. // the IP layer
  519. //
  520. if (pPktHeader->EtherType == NET_SHORT(AA_PKT_ETHERTYPE_IP))
  521. {
  522. AADEBUGP(AAD_EXTRA_LOUD,
  523. ("Rcv: VC 0x%x, NDISpkt 0x%x: EtherType is IP, passing up\n"));
  524. #if DBG
  525. if (AaDataDebugLevel & AAD_DATA_IN)
  526. {
  527. IP_ADDRESS IPAddress;
  528. if ((pVc->pAtmEntry != NULL_PATMARP_ATM_ENTRY) &&
  529. (pVc->pAtmEntry->pIpEntryList != NULL_PATMARP_IP_ENTRY))
  530. {
  531. IPAddress = pVc->pAtmEntry->pIpEntryList->IPAddress;
  532. }
  533. else
  534. {
  535. IPAddress = 0;
  536. }
  537. AADEBUGP(AAD_WARNING,
  538. ("%d <= %d.%d.%d.%d\n",
  539. TotalLength,
  540. ((PUCHAR)&IPAddress)[0],
  541. ((PUCHAR)&IPAddress)[1],
  542. ((PUCHAR)&IPAddress)[2],
  543. ((PUCHAR)&IPAddress)[3]));
  544. }
  545. #endif // DBG
  546. if (IsNonUnicast)
  547. {
  548. AA_IF_STAT_INCR(pInterface, InNonUnicastPkts);
  549. }
  550. else
  551. {
  552. AA_IF_STAT_INCR(pInterface, InUnicastPkts);
  553. }
  554. #ifdef _PNP_POWER_
  555. if (NDIS_GET_PACKET_STATUS(pNdisPacket) != NDIS_STATUS_RESOURCES)
  556. {
  557. UINT HeaderSize;
  558. UINT DataSize;
  559. #define ATMARP_MIN_1ST_RECV_BUFSIZE 512
  560. HeaderSize = NDIS_GET_PACKET_HEADER_SIZE(pNdisPacket);
  561. //
  562. // 2/8/1998 JosephJ
  563. // We set DataSize to the total payload size,
  564. // unless the first buffer is too small to
  565. // hold the IP header. In the latter case,
  566. // we set DataSize to be the size of the 1st buffer
  567. // (minus the LLS/SNAP header size).
  568. //
  569. // This is to work around a bug in tcpip.
  570. //
  571. // 2/25/1998 JosephJ
  572. // Unfortunately we have to back out YET AGAIN
  573. // because large pings (eg ping -l 4000) doesn't
  574. // work -- bug#297784
  575. // Hence the "0" in "0 && DataSize" below.
  576. // Take out the "0" to put back the per fix.
  577. //
  578. DataSize = BufferLength - sizeof(AA_PKT_LLC_SNAP_HEADER);
  579. if (0 && DataSize >= ATMARP_MIN_1ST_RECV_BUFSIZE)
  580. {
  581. DataSize = TotalLength - sizeof(AA_PKT_LLC_SNAP_HEADER);
  582. }
  583. (pInterface->IPRcvPktHandler)(
  584. pInterface->IPContext,
  585. (PVOID)((PUCHAR)pPktHeader+sizeof(AA_PKT_LLC_SNAP_HEADER)),
  586. DataSize,
  587. TotalLength,
  588. (NDIS_HANDLE)pNdisPacket,
  589. sizeof(AA_PKT_LLC_SNAP_HEADER),
  590. IsNonUnicast,
  591. 0,
  592. pNdisBuffer,
  593. &ReturnCount
  594. #if P2MP
  595. ,NULL
  596. #endif //P2MP
  597. );
  598. }
  599. else
  600. {
  601. (pInterface->IPRcvHandler)(
  602. pInterface->IPContext,
  603. (PVOID)((PUCHAR)pPktHeader+sizeof(AA_PKT_LLC_SNAP_HEADER)),
  604. BufferLength - sizeof(AA_PKT_LLC_SNAP_HEADER),
  605. TotalLength - sizeof(AA_PKT_LLC_SNAP_HEADER),
  606. (NDIS_HANDLE)pNdisPacket,
  607. sizeof(AA_PKT_LLC_SNAP_HEADER),
  608. IsNonUnicast
  609. #if P2MP
  610. ,NULL
  611. #endif //P2MP
  612. );
  613. }
  614. #else
  615. // For Win98:
  616. (pInterface->IPRcvHandler)(
  617. pInterface->IPContext,
  618. (PVOID)((PUCHAR)pPktHeader+sizeof(AA_PKT_LLC_SNAP_HEADER)),
  619. BufferLength - sizeof(AA_PKT_LLC_SNAP_HEADER),
  620. TotalLength - sizeof(AA_PKT_LLC_SNAP_HEADER),
  621. (NDIS_HANDLE)pNdisPacket,
  622. sizeof(AA_PKT_LLC_SNAP_HEADER),
  623. IsNonUnicast
  624. #if P2MP
  625. ,NULL
  626. #endif //P2MP
  627. );
  628. #endif // _PNP_POWER_
  629. }
  630. else if (pPktHeader->EtherType == NET_SHORT(AA_PKT_ETHERTYPE_ARP))
  631. {
  632. //
  633. // An ARP packet: we handle it ourselves
  634. //
  635. AA_ASSERT(BufferLength == TotalLength);
  636. AA_IF_STAT_INCR(pInterface, InUnicastPkts);
  637. AtmArpHandleARPPacket(
  638. pVc,
  639. pPktHeader,
  640. BufferLength
  641. );
  642. }
  643. else
  644. {
  645. //
  646. // Discard packet -- bad EtherType
  647. //
  648. AADEBUGP(AAD_WARNING, ("VC: 0x%x, Pkt hdr 0x%x, bad EtherType 0x%x\n",
  649. pVc, pPktHeader, (ULONG)pPktHeader->EtherType));
  650. Discarded = TRUE;
  651. AA_IF_STAT_INCR(pInterface, UnknownProtos);
  652. }
  653. }
  654. else
  655. {
  656. #ifdef IPMCAST
  657. Discarded = AtmArpMcProcessPacket(
  658. pVc,
  659. pNdisPacket,
  660. pNdisBuffer,
  661. pPktHeader,
  662. TotalLength,
  663. BufferLength
  664. );
  665. #else
  666. //
  667. // Discard packet -- bad LLC/SNAP
  668. //
  669. AADEBUGP(AAD_WARNING, ("VC: 0x%x, Pkt hdr 0x%x, bad LLC/SNAP\n",
  670. pVc, pPktHeader));
  671. Discarded = TRUE;
  672. #endif // IPMCAST
  673. }
  674. }
  675. else
  676. {
  677. //
  678. // Discard packet -- too short
  679. //
  680. AADEBUGP(AAD_WARNING, ("VC: 0x%x, Pkt hdr 0x%x, too short: %d\n",
  681. pVc, pPktHeader, TotalLength));
  682. Discarded = TRUE;
  683. }
  684. }
  685. else
  686. {
  687. //
  688. // Discard packet -- IF down
  689. //
  690. AADEBUGP(AAD_WARNING, ("pInterface: 0x%x is down, discarding NDIS pkt 0x%x\n",
  691. pInterface, pNdisPacket));
  692. Discarded = TRUE;
  693. }
  694. if (Discarded)
  695. {
  696. AA_IF_STAT_INCR(pInterface, InDiscards);
  697. }
  698. return (ReturnCount);
  699. }
  700. VOID
  701. AtmArpHandleARPPacket(
  702. IN PATMARP_VC pVc,
  703. IN PAA_PKT_LLC_SNAP_HEADER pPktHeader,
  704. IN ULONG PacketLength
  705. )
  706. /*++
  707. Routine Description:
  708. Process a received ARP packet. We complete most of the packet checks
  709. here, and then branch off to do different things based on the Op type
  710. in the packet.
  711. We do not hang on to the packet, i.e. when we return from here,
  712. the packet is free.
  713. Arguments:
  714. pVc - Pointer to ATMARP VC on which packet arrived
  715. pPktHeader - Pointer to start of packet (including LLC/SNAP)
  716. PacketLength - Length including LLC/SNAP header
  717. Return Value:
  718. None
  719. --*/
  720. {
  721. PATMARP_INTERFACE pInterface;
  722. PAA_ARP_PKT_HEADER pArpHeader;
  723. NDIS_STATUS Status;
  724. //
  725. // For walking down the packet
  726. //
  727. UCHAR UNALIGNED * pPacket;
  728. //
  729. // For storing pointers to the packet contents. We'll need this
  730. // if we have to send a reply packet.
  731. //
  732. AA_ARP_PKT_CONTENTS ArpContents;
  733. BOOLEAN SrcAtmBelongsToUs;
  734. BOOLEAN SrcIPBelongsToUs;
  735. //
  736. // Initialize (Important: don't remove the zeroing of ArpContents)
  737. //
  738. AA_SET_MEM((PUCHAR)&ArpContents, 0, sizeof(AA_ARP_PKT_CONTENTS));
  739. Status = NDIS_STATUS_SUCCESS;
  740. pInterface = pVc->pInterface;
  741. pArpHeader = STRUCT_OF(AA_ARP_PKT_HEADER, pPktHeader, LLCSNAPHeader);
  742. AADEBUGP(AAD_EXTRA_LOUD+10,
  743. ("HandleARPPkt: VC 0x%x, IF 0x%x, pPktHdr 0x%x, Len %d\n",
  744. pVc,
  745. pInterface,
  746. pPktHeader,
  747. PacketLength));
  748. do
  749. {
  750. if (PacketLength < AA_ARP_PKT_HEADER_LENGTH)
  751. {
  752. AADEBUGP(AAD_WARNING, ("HandleARPPkt: IF 0x%x, PacketLength %d < HdrLen %d\n",
  753. pInterface, PacketLength, AA_ARP_PKT_HEADER_LENGTH));
  754. Status = NDIS_STATUS_BUFFER_TOO_SHORT;
  755. break;
  756. }
  757. if ((pArpHeader->hrd != NET_SHORT(AA_PKT_HRD)) ||
  758. (pArpHeader->pro != NET_SHORT(AA_PKT_PRO)))
  759. {
  760. AADEBUGP(AAD_WARNING,
  761. ("HandleARPPkt: IF 0x%x, Bad hdr (%d != %d) or pro (%d != %d)\n",
  762. pInterface,
  763. pArpHeader->hrd,
  764. AA_PKT_HRD,
  765. pArpHeader->pro,
  766. AA_PKT_PRO));
  767. Status = NDIS_STATUS_NOT_RECOGNIZED;
  768. break;
  769. }
  770. //
  771. // Get at the variable part of the packet, and get pointers
  772. // to all addresses.
  773. //
  774. // TBD: add more checks on ATM address lengths and combinations
  775. // Note: we check for packet length later.
  776. //
  777. pPacket = pArpHeader->Variable;
  778. //
  779. // Source ATM Number
  780. //
  781. if (pArpHeader->shtl != 0)
  782. {
  783. ArpContents.SrcAtmNumberTypeLen = pArpHeader->shtl;
  784. ArpContents.pSrcAtmNumber = pPacket;
  785. pPacket += (pArpHeader->shtl & ~AA_PKT_ATM_ADDRESS_BIT);
  786. }
  787. //
  788. // Source ATM Subaddress
  789. //
  790. if (pArpHeader->sstl != 0)
  791. {
  792. ArpContents.SrcAtmSubaddrTypeLen = pArpHeader->sstl;
  793. ArpContents.pSrcAtmSubaddress = pPacket;
  794. pPacket += (pArpHeader->sstl & ~AA_PKT_ATM_ADDRESS_BIT);
  795. }
  796. //
  797. // Source IP Address. Older 1577 implementations may send an
  798. // IP address field filled with all 0's to denote an unspecified
  799. // IP address.
  800. //
  801. if (pArpHeader->spln != 0)
  802. {
  803. if (pArpHeader->spln != AA_IPV4_ADDRESS_LENGTH)
  804. {
  805. AADEBUGP(AAD_WARNING,
  806. ("HandleARPPkt: IF 0x%x, bad spln %d != %d\n",
  807. pInterface,
  808. pArpHeader->spln,
  809. AA_IPV4_ADDRESS_LENGTH));
  810. Status = NDIS_STATUS_INVALID_ADDRESS;
  811. break;
  812. }
  813. if (!AtmArpIsZeroIPAddress(pPacket))
  814. {
  815. ArpContents.pSrcIPAddress = pPacket;
  816. }
  817. pPacket += AA_IPV4_ADDRESS_LENGTH;
  818. }
  819. //
  820. // Target ATM Number
  821. //
  822. if (pArpHeader->thtl != 0)
  823. {
  824. ArpContents.DstAtmNumberTypeLen = pArpHeader->thtl;
  825. ArpContents.pDstAtmNumber = pPacket;
  826. pPacket += (pArpHeader->thtl & ~AA_PKT_ATM_ADDRESS_BIT);
  827. }
  828. //
  829. // Target ATM Subaddress
  830. //
  831. if (pArpHeader->tstl != 0)
  832. {
  833. ArpContents.DstAtmSubaddrTypeLen = pArpHeader->tstl;
  834. ArpContents.pDstAtmSubaddress = pPacket;
  835. pPacket += (pArpHeader->tstl & ~AA_PKT_ATM_ADDRESS_BIT);
  836. }
  837. //
  838. // Target IP Address [see comments for Source IP Address]
  839. //
  840. if (pArpHeader->tpln != 0)
  841. {
  842. if (pArpHeader->tpln != AA_IPV4_ADDRESS_LENGTH)
  843. {
  844. AADEBUGP(AAD_WARNING,
  845. ("HandleARPPkt: IF 0x%x, bad tpln %d != %d\n",
  846. pInterface,
  847. pArpHeader->tpln,
  848. AA_IPV4_ADDRESS_LENGTH));
  849. Status = NDIS_STATUS_INVALID_ADDRESS;
  850. break;
  851. }
  852. if (!AtmArpIsZeroIPAddress(pPacket))
  853. {
  854. ArpContents.pDstIPAddress = pPacket;
  855. }
  856. pPacket += AA_IPV4_ADDRESS_LENGTH;
  857. }
  858. //
  859. //
  860. //
  861. if ((ULONG)(pPacket - (PUCHAR)pArpHeader) > PacketLength)
  862. {
  863. AADEBUGP(AAD_WARNING,
  864. ("HandleARPPkt: IF 0x%x, pPktHdr 0x%x. Length %d TOO SMALL (want %d)\n",
  865. pInterface,
  866. pArpHeader,
  867. PacketLength,
  868. (pPacket - (PUCHAR)pArpHeader)));
  869. Status = NDIS_STATUS_BUFFER_TOO_SHORT;
  870. break;
  871. }
  872. //
  873. // If this is an ARP NAK packet, swap Source and Target
  874. // addresses, in preparation for what follows. This is
  875. // because, unlike any other Reply packet where the Source
  876. // and Target addresses get swapped, the ARP NAK
  877. // packet is a copy of the ARP Request, with only the
  878. // Op code changed.
  879. //
  880. if (NET_SHORT(pArpHeader->op) == AA_PKT_OP_TYPE_ARP_NAK)
  881. {
  882. UCHAR TypeLen;
  883. UCHAR UNALIGNED * pAddress;
  884. //
  885. // IP Addresses:
  886. //
  887. pAddress = ArpContents.pSrcIPAddress;
  888. ArpContents.pSrcIPAddress = ArpContents.pDstIPAddress;
  889. ArpContents.pDstIPAddress = pAddress;
  890. //
  891. // ATM Number:
  892. //
  893. TypeLen = ArpContents.SrcAtmNumberTypeLen;
  894. ArpContents.SrcAtmNumberTypeLen = ArpContents.DstAtmNumberTypeLen;
  895. ArpContents.DstAtmNumberTypeLen = TypeLen;
  896. pAddress = ArpContents.pSrcAtmNumber;
  897. ArpContents.pSrcAtmNumber = ArpContents.pDstAtmNumber;
  898. ArpContents.pDstAtmNumber = pAddress;
  899. //
  900. // ATM Subaddress:
  901. //
  902. TypeLen = ArpContents.SrcAtmSubaddrTypeLen;
  903. ArpContents.SrcAtmSubaddrTypeLen = ArpContents.DstAtmSubaddrTypeLen;
  904. ArpContents.DstAtmSubaddrTypeLen = TypeLen;
  905. pAddress = ArpContents.pSrcAtmSubaddress;
  906. ArpContents.pSrcAtmSubaddress = ArpContents.pDstAtmSubaddress;
  907. ArpContents.pDstAtmSubaddress = pAddress;
  908. }
  909. SrcIPBelongsToUs = AtmArpIsLocalIPAddress(
  910. pInterface,
  911. ArpContents.pSrcIPAddress
  912. );
  913. SrcAtmBelongsToUs = AtmArpIsLocalAtmAddress(
  914. pInterface,
  915. ArpContents.pSrcAtmNumber,
  916. ArpContents.SrcAtmNumberTypeLen
  917. );
  918. //
  919. // Check if someone else is claiming to be the owner
  920. // of "our" IP address:
  921. //
  922. if (SrcIPBelongsToUs && !SrcAtmBelongsToUs)
  923. {
  924. AADEBUGP(AAD_ERROR,
  925. ("Pkt 0x%x: src IP is ours, src ATM is bad!\n", pPktHeader));
  926. AA_ACQUIRE_IF_LOCK(pInterface);
  927. pInterface->State = IF_STATUS_DOWN;
  928. pInterface->LastChangeTime = GetTimeTicks();
  929. AA_RELEASE_IF_LOCK(pInterface);
  930. AtmArpStartRegistration(pInterface);
  931. Status = NDIS_STATUS_NOT_RECOGNIZED;
  932. break;
  933. }
  934. //
  935. // See if this is directed to someone else: if so, drop it.
  936. //
  937. //
  938. // Check if the Target IP address is ours. A null IP address is
  939. // acceptable (e.g. [In]ARP Request).
  940. //
  941. if ((ArpContents.pDstIPAddress != (PUCHAR)NULL) &&
  942. !AtmArpIsLocalIPAddress(pInterface, ArpContents.pDstIPAddress))
  943. {
  944. //
  945. // A target IP address is present, and it is not ours
  946. //
  947. AADEBUGP(AAD_WARNING,
  948. ("ArpPkt 0x%x has unknown target IP addr (%d.%d.%d.%d)\n",
  949. pPktHeader,
  950. ArpContents.pDstIPAddress[0],
  951. ArpContents.pDstIPAddress[1],
  952. ArpContents.pDstIPAddress[2],
  953. ArpContents.pDstIPAddress[3]));
  954. Status = NDIS_STATUS_NOT_RECOGNIZED;
  955. break;
  956. }
  957. //
  958. // If there is a Target ATM Number, check to see if it is ours.
  959. //
  960. if ((ArpContents.pDstAtmNumber != (PUCHAR)NULL) &&
  961. (!AtmArpIsLocalAtmAddress(
  962. pInterface,
  963. ArpContents.pDstAtmNumber,
  964. ArpContents.DstAtmNumberTypeLen))
  965. )
  966. {
  967. //
  968. // A target ATM number is present, and it is not ours
  969. //
  970. AADEBUGP(AAD_WARNING,
  971. ("ArpPkt 0x%x has unknown target ATM addr (0x%x, 0x%x)\n",
  972. pPktHeader,
  973. ArpContents.DstAtmNumberTypeLen,
  974. ArpContents.pDstAtmNumber));
  975. Status = NDIS_STATUS_NOT_RECOGNIZED;
  976. break;
  977. }
  978. //
  979. // Handle the various Op types
  980. //
  981. switch (NET_SHORT(pArpHeader->op))
  982. {
  983. case AA_PKT_OP_TYPE_ARP_REQUEST:
  984. AtmArpHandleARPRequest(
  985. pVc,
  986. pInterface,
  987. pArpHeader,
  988. &ArpContents
  989. );
  990. break;
  991. case AA_PKT_OP_TYPE_ARP_REPLY:
  992. AtmArpHandleARPReply(
  993. pVc,
  994. pInterface,
  995. pArpHeader,
  996. &ArpContents,
  997. SrcIPBelongsToUs,
  998. SrcAtmBelongsToUs
  999. );
  1000. break;
  1001. case AA_PKT_OP_TYPE_ARP_NAK:
  1002. AtmArpHandleARPNAK(
  1003. pVc,
  1004. pInterface,
  1005. pArpHeader,
  1006. &ArpContents
  1007. );
  1008. break;
  1009. case AA_PKT_OP_TYPE_INARP_REQUEST:
  1010. AtmArpHandleInARPRequest(
  1011. pVc,
  1012. pInterface,
  1013. pArpHeader,
  1014. &ArpContents
  1015. );
  1016. break;
  1017. case AA_PKT_OP_TYPE_INARP_REPLY:
  1018. AtmArpHandleInARPReply(
  1019. pVc,
  1020. pInterface,
  1021. pArpHeader,
  1022. &ArpContents
  1023. );
  1024. break;
  1025. default:
  1026. AADEBUGP(AAD_WARNING,
  1027. ("HandleARPPkt: IF 0x%x, pArpHdr 0x%x, Op %d not known\n",
  1028. pInterface, pArpHeader, NET_SHORT(pArpHeader->op)));
  1029. Status = NDIS_STATUS_NOT_RECOGNIZED;
  1030. break;
  1031. }
  1032. }
  1033. while (FALSE);
  1034. return;
  1035. }
  1036. VOID
  1037. AtmArpHandleARPRequest(
  1038. IN PATMARP_VC pVc,
  1039. IN PATMARP_INTERFACE pInterface,
  1040. IN PAA_ARP_PKT_HEADER pArpHeader,
  1041. IN PAA_ARP_PKT_CONTENTS pArpContents
  1042. )
  1043. /*++
  1044. Routine Description:
  1045. Process a received ATMARP Request. All we need to do is send
  1046. an ATMARP Reply, since the calling routine has already verified
  1047. that the Target IP address is ours.
  1048. Arguments:
  1049. pVc - Pointer to VC on which the request arrived
  1050. pInterface - Pointer to ATMARP Interface containing this VC
  1051. pArpHeader - Pointer to ARP Header for this packet
  1052. pArpContents - Parsed contents of received ARP Request packet
  1053. Return Value:
  1054. None
  1055. --*/
  1056. {
  1057. //
  1058. // Temp locations used for swapping fields
  1059. //
  1060. UCHAR UNALIGNED * pAddress;
  1061. UCHAR Length;
  1062. //
  1063. // ARP Reply packet
  1064. //
  1065. PNDIS_PACKET pNdisPacket;
  1066. PUCHAR pArpPacket;
  1067. //
  1068. // Swap source and target addresses, and fill in our ATM info
  1069. // in the source ATM addresses fields.
  1070. //
  1071. //
  1072. // IP Addresses
  1073. //
  1074. pAddress = pArpContents->pSrcIPAddress;
  1075. pArpContents->pSrcIPAddress = pArpContents->pDstIPAddress;
  1076. pArpContents->pDstIPAddress = pAddress;
  1077. //
  1078. // ATM Numbers: set the target ATM number to the source ATM
  1079. // number, but set the source ATM number to the local ATM
  1080. // address.
  1081. //
  1082. pArpContents->pDstAtmNumber = pArpContents->pSrcAtmNumber;
  1083. pArpContents->DstAtmNumberTypeLen = pArpContents->SrcAtmNumberTypeLen;
  1084. pArpContents->pSrcAtmNumber = (pInterface->LocalAtmAddress.Address);
  1085. pArpContents->SrcAtmNumberTypeLen =
  1086. AA_PKT_ATM_ADDRESS_TO_TYPE_LEN(&(pInterface->LocalAtmAddress));
  1087. //
  1088. // ATM Subaddresses
  1089. //
  1090. pArpContents->pDstAtmSubaddress = pArpContents->pSrcAtmSubaddress;
  1091. pArpContents->DstAtmSubaddrTypeLen = pArpContents->SrcAtmSubaddrTypeLen;
  1092. pArpContents->pSrcAtmSubaddress = NULL;
  1093. pArpContents->SrcAtmSubaddrTypeLen = 0;
  1094. //
  1095. // Build the ARP Reply packet
  1096. //
  1097. pNdisPacket = AtmArpBuildARPPacket(
  1098. AA_PKT_OP_TYPE_ARP_REPLY,
  1099. pInterface,
  1100. &pArpPacket,
  1101. pArpContents
  1102. );
  1103. if (pNdisPacket != (PNDIS_PACKET)NULL)
  1104. {
  1105. //
  1106. // And send it off. Since we are in the context of a receive
  1107. // indication on this VC, we can safely access the VC now.
  1108. //
  1109. AA_ACQUIRE_VC_LOCK(pVc);
  1110. AtmArpSendPacketOnVc(pVc, pNdisPacket);
  1111. //
  1112. // The VC lock is released by SendPacketOnVc
  1113. //
  1114. }
  1115. }
  1116. VOID
  1117. AtmArpHandleARPReply(
  1118. IN PATMARP_VC pVc,
  1119. IN PATMARP_INTERFACE pInterface,
  1120. IN PAA_ARP_PKT_HEADER pArpHeader,
  1121. IN PAA_ARP_PKT_CONTENTS pArpContents,
  1122. IN BOOLEAN SrcIPAddressIsOurs,
  1123. IN BOOLEAN SrcAtmAddressIsOurs
  1124. )
  1125. /*++
  1126. Routine Description:
  1127. Process a received ATMARP Reply packet. There are two major
  1128. cases here:
  1129. (1) We were trying to register one of our IP addresses with
  1130. the server.
  1131. (2) We were trying to resolve a remote IP address.
  1132. In case (1), if we just registered the first of possibly many
  1133. IP addresses assigned to this interface, we register all the other
  1134. IP addresses.
  1135. In case (2), we set up an IP to ATM mapping and initiate a connection
  1136. if necessary.
  1137. Arguments:
  1138. pVc - Pointer to VC on which the reply arrived
  1139. pInterface - Pointer to ATMARP Interface containing this VC
  1140. pArpHeader - Pointer to ARP Header for this packet
  1141. pArpContents - Parsed contents of received ARP Request packet
  1142. SrcIPAddressIsOurs - The source IP address is one of ours
  1143. SrcAtmAddressIsOurs - The source ATM info is ours.
  1144. Return Value:
  1145. None
  1146. --*/
  1147. {
  1148. BOOLEAN TimerWasRunning;
  1149. BOOLEAN IsFirstRegistration;
  1150. PIP_ADDRESS_ENTRY pIPAddressEntry;
  1151. ULONG rc; // Ref Count
  1152. AADEBUGP(AAD_LOUD,
  1153. ("Handle ARP Reply: pVc 0x%x, pIf 0x%x, IF Flags 0x%x, OurIP %d, OurATM %d\n",
  1154. pVc, pInterface, pInterface->Flags, SrcIPAddressIsOurs, SrcAtmAddressIsOurs));
  1155. AA_ACQUIRE_IF_LOCK(pInterface);
  1156. if (AA_IS_FLAG_SET(
  1157. pInterface->Flags,
  1158. AA_IF_SERVER_STATE_MASK,
  1159. AA_IF_SERVER_REGISTERING))
  1160. {
  1161. //
  1162. // We just completed registering with the server. Since we don't
  1163. // send ARP requests to resolve any other addresses while we
  1164. // are registering, the Source IP address must be ours.
  1165. //
  1166. //
  1167. // Stop the Registration timer
  1168. //
  1169. TimerWasRunning = AtmArpStopTimer(&(pInterface->Timer), pInterface);
  1170. AA_ASSERT(TimerWasRunning == TRUE);
  1171. if (TimerWasRunning)
  1172. {
  1173. rc = AtmArpDereferenceInterface(pInterface); // Timer reference
  1174. AA_ASSERT(rc > 0);
  1175. }
  1176. //
  1177. // We have already verified that the Target addresses are ours.
  1178. // Check that the source addresses are ours, too.
  1179. //
  1180. if (!SrcIPAddressIsOurs || !SrcAtmAddressIsOurs)
  1181. {
  1182. //
  1183. // Registration failure. Start recovery.
  1184. //
  1185. AtmArpHandleServerRegistrationFailure(pInterface, pVc);
  1186. //
  1187. // IF lock is released within the above.
  1188. //
  1189. }
  1190. else
  1191. {
  1192. //
  1193. // We registered an IP address successfully!
  1194. //
  1195. // Find the entry for the IP Address that we have registered,
  1196. // and mark it as registered.
  1197. //
  1198. pIPAddressEntry = &(pInterface->LocalIPAddress);
  1199. while (*((IP_ADDRESS UNALIGNED *)(pArpContents->pSrcIPAddress))
  1200. != pIPAddressEntry->IPAddress)
  1201. {
  1202. AA_ASSERT(pIPAddressEntry->pNext != (PIP_ADDRESS_ENTRY)NULL);
  1203. pIPAddressEntry = pIPAddressEntry->pNext;
  1204. }
  1205. pIPAddressEntry->IsRegistered = TRUE;
  1206. IsFirstRegistration = pIPAddressEntry->IsFirstRegistration;
  1207. pIPAddressEntry->IsFirstRegistration = FALSE;
  1208. AADEBUGP(AAD_INFO,
  1209. ("**** Registered IP Addr: %d.%d.%d.%d on IF 0x%x\n",
  1210. ((PUCHAR)&(pIPAddressEntry->IPAddress))[0],
  1211. ((PUCHAR)&(pIPAddressEntry->IPAddress))[1],
  1212. ((PUCHAR)&(pIPAddressEntry->IPAddress))[2],
  1213. ((PUCHAR)&(pIPAddressEntry->IPAddress))[3],
  1214. pInterface));
  1215. AA_SET_FLAG(
  1216. pInterface->Flags,
  1217. AA_IF_SERVER_STATE_MASK,
  1218. AA_IF_SERVER_REGISTERED);
  1219. pInterface->State = IF_STATUS_UP;
  1220. pInterface->LastChangeTime = GetTimeTicks();
  1221. //
  1222. // Start the Server refresh timer so that we send our ARP info
  1223. // to the server every so often (default = 15 minutes).
  1224. //
  1225. AtmArpStartTimer(
  1226. pInterface,
  1227. &(pInterface->Timer),
  1228. AtmArpServerRefreshTimeout,
  1229. pInterface->ServerRefreshTimeout,
  1230. (PVOID)pInterface // Context
  1231. );
  1232. AtmArpReferenceInterface(pInterface); // Timer reference
  1233. //
  1234. // If we have any more addresses to register, do so now.
  1235. //
  1236. AtmArpRegisterOtherIPAddresses(pInterface);
  1237. //
  1238. // IF Lock is freed in the above
  1239. //
  1240. #ifdef ATMARP_WMI
  1241. if (IsFirstRegistration)
  1242. {
  1243. //
  1244. // Send a WMI event, which carries the list of IP Addresses
  1245. // registered on this IF. We do this only if this is a new
  1246. // IP address.
  1247. //
  1248. AtmArpWmiSendTCIfIndication(
  1249. pInterface,
  1250. AAGID_QOS_TC_INTERFACE_UP_INDICATION,
  1251. 0
  1252. );
  1253. }
  1254. #endif
  1255. }
  1256. }
  1257. else
  1258. {
  1259. //
  1260. // Resolved an IP to ATM address
  1261. //
  1262. AADEBUGP(AAD_INFO,
  1263. ("ARP Reply: Resolved IP Addr: %d.%d.%d.%d\n",
  1264. ((PUCHAR)(pArpContents->pSrcIPAddress))[0],
  1265. ((PUCHAR)(pArpContents->pSrcIPAddress))[1],
  1266. ((PUCHAR)(pArpContents->pSrcIPAddress))[2],
  1267. ((PUCHAR)(pArpContents->pSrcIPAddress))[3]
  1268. ));
  1269. AA_RELEASE_IF_LOCK(pInterface);
  1270. (VOID)AtmArpLearnIPToAtm(
  1271. pInterface,
  1272. (IP_ADDRESS *)pArpContents->pSrcIPAddress,
  1273. pArpContents->SrcAtmNumberTypeLen,
  1274. pArpContents->pSrcAtmNumber,
  1275. pArpContents->SrcAtmSubaddrTypeLen,
  1276. pArpContents->pSrcAtmSubaddress,
  1277. FALSE // Not a static entry
  1278. );
  1279. }
  1280. return;
  1281. }
  1282. VOID
  1283. AtmArpHandleARPNAK(
  1284. IN PATMARP_VC pVc,
  1285. IN PATMARP_INTERFACE pInterface,
  1286. IN PAA_ARP_PKT_HEADER pArpHeader,
  1287. IN PAA_ARP_PKT_CONTENTS pArpContents
  1288. )
  1289. /*++
  1290. Routine Description:
  1291. Process a received ARP-NAK packet. If this is in response to
  1292. an ARP Request we had sent to register ourselves, then we close
  1293. the VC to this ARP server, and try the next server in our list of
  1294. servers, after waiting for a while.
  1295. If we were trying to resolve a remote IP address, then we mark
  1296. the ARP IP entry corresponding to this IP address as having
  1297. received a NAK, and free any packets queued on this. We also make
  1298. a timestamp on the Entry so that we don't send another ARP Request
  1299. for the same IP address very soon.
  1300. Arguments:
  1301. pVc - Pointer to VC on which the NAK arrived
  1302. pInterface - Pointer to ATMARP Interface containing this VC
  1303. pArpHeader - Pointer to ARP Header for this packet
  1304. pArpContents - Parsed contents of received ARP Request packet
  1305. Return Value:
  1306. None
  1307. --*/
  1308. {
  1309. BOOLEAN TimerWasRunning;
  1310. ULONG rc; // Ref Count
  1311. PATMARP_IP_ENTRY pIpEntry;
  1312. PNDIS_PACKET PacketList; // Packets queued for sending
  1313. #if !BINARY_COMPATIBLE
  1314. #ifdef CUBDD
  1315. SINGLE_LIST_ENTRY PendingIrpList;
  1316. #endif // CUBDD
  1317. #endif // !BINARY_COMPATIBLE
  1318. AA_ACQUIRE_IF_LOCK(pInterface);
  1319. if (AA_IS_FLAG_SET(
  1320. pInterface->Flags,
  1321. AA_IF_SERVER_STATE_MASK,
  1322. AA_IF_SERVER_REGISTERING))
  1323. {
  1324. AADEBUGP(AAD_WARNING,
  1325. ("Rcvd ARP NAK while registering: pIf 0x%x\n", pInterface));
  1326. //
  1327. // Registration was in progress, and it failed. Start recovery.
  1328. //
  1329. AtmArpHandleServerRegistrationFailure(pInterface, pVc);
  1330. //
  1331. // IF lock is released within the above.
  1332. //
  1333. }
  1334. else
  1335. {
  1336. //
  1337. // We were trying to resolve an IP address. Get the Address
  1338. // IP Entry corresponding to this IP address.
  1339. //
  1340. AA_RELEASE_IF_LOCK(pInterface);
  1341. AA_ACQUIRE_IF_TABLE_LOCK(pInterface);
  1342. pIpEntry = AtmArpSearchForIPAddress(
  1343. pInterface,
  1344. (IP_ADDRESS *)pArpContents->pSrcIPAddress,
  1345. IE_REFTYPE_TMP,
  1346. FALSE, // this isn't multicast/broadcast
  1347. FALSE // Don't create a new one
  1348. );
  1349. AA_RELEASE_IF_TABLE_LOCK(pInterface);
  1350. if (pIpEntry != NULL_PATMARP_IP_ENTRY)
  1351. {
  1352. AADEBUGP(AAD_INFO,
  1353. ("Rcvd ARP NAK: pIf 0x%x, IP addr %d:%d:%d:%d\n",
  1354. pInterface,
  1355. ((PUCHAR)(&(pIpEntry->IPAddress)))[0],
  1356. ((PUCHAR)(&(pIpEntry->IPAddress)))[1],
  1357. ((PUCHAR)(&(pIpEntry->IPAddress)))[2],
  1358. ((PUCHAR)(&(pIpEntry->IPAddress)))[3]));
  1359. AA_ACQUIRE_IE_LOCK(pIpEntry);
  1360. AA_ASSERT(AA_IE_IS_ALIVE(pIpEntry));
  1361. //
  1362. // AtmArpSerchForIPAddress addrefd pIpEntry for us -- we deref it
  1363. // here now that we've locked it.
  1364. //
  1365. rc = AA_DEREF_IE(pIpEntry, IE_REFTYPE_TMP);
  1366. if (rc > 0)
  1367. {
  1368. #if !BINARY_COMPATIBLE
  1369. #ifdef CUBDD
  1370. //
  1371. // Take out the list of pending IRPs on this IP Entry.
  1372. //
  1373. PendingIrpList = pIpEntry->PendingIrpList;
  1374. pIpEntry->PendingIrpList.Next = (PSINGLE_LIST_ENTRY)NULL;
  1375. #endif // CUBDD
  1376. #endif // !BINARY_COMPATIBLE
  1377. //
  1378. // Take out all packets queued on this entry
  1379. //
  1380. PacketList = pIpEntry->PacketList;
  1381. pIpEntry->PacketList = (PNDIS_PACKET)NULL;
  1382. //
  1383. // The Address resolution timer must be running on this Entry;
  1384. // stop it.
  1385. //
  1386. TimerWasRunning = AtmArpStopTimer(&(pIpEntry->Timer), pInterface);
  1387. if (TimerWasRunning)
  1388. {
  1389. rc = AA_DEREF_IE(pIpEntry, IE_REFTYPE_TIMER); // Timer reference
  1390. }
  1391. else
  1392. {
  1393. rc = pIpEntry->RefCount;
  1394. }
  1395. }
  1396. //
  1397. // Continue only if the IP Entry hasn't gone away
  1398. //
  1399. if (rc > 0)
  1400. {
  1401. //
  1402. // Set the IP entry's state so that we don't send any
  1403. // address resolution traffic for this IP address for
  1404. // some time.
  1405. //
  1406. AA_SET_FLAG(pIpEntry->Flags,
  1407. AA_IP_ENTRY_STATE_MASK,
  1408. AA_IP_ENTRY_SEEN_NAK);
  1409. //
  1410. // Start a NAK Delay timer: until this expires, we won't
  1411. // send any ARP requests for this IP address. This makes
  1412. // sure that we don't keep pounding on the server with
  1413. // an unresolvable IP address.
  1414. //
  1415. AtmArpStartTimer(
  1416. pInterface,
  1417. &(pIpEntry->Timer),
  1418. AtmArpNakDelayTimeout,
  1419. pInterface->MinWaitAfterNak,
  1420. (PVOID)pIpEntry // Context
  1421. );
  1422. AA_REF_IE(pIpEntry, IE_REFTYPE_TIMER); // Timer ref
  1423. AA_RELEASE_IE_LOCK(pIpEntry);
  1424. }
  1425. // else the IP Entry lock would have been released.
  1426. //
  1427. // Free any packets that were queued up.
  1428. //
  1429. if (PacketList != (PNDIS_PACKET)NULL)
  1430. {
  1431. AtmArpFreeSendPackets(
  1432. pInterface,
  1433. PacketList,
  1434. FALSE // No headers on these
  1435. );
  1436. }
  1437. #if !BINARY_COMPATIBLE
  1438. #ifdef CUBDD
  1439. AtmArpCompleteArpIrpList(
  1440. PendingIrpList,
  1441. (PATM_ADDRESS)NULL
  1442. );
  1443. #endif // CUBDD
  1444. #endif // !BINARY_COMPATIBLE
  1445. }
  1446. else
  1447. {
  1448. //
  1449. // No IP Address Entry matching the IP address being
  1450. // ARP'ed for. Nothing to be done in this case.
  1451. //
  1452. }
  1453. }
  1454. return;
  1455. }
  1456. VOID
  1457. AtmArpHandleInARPRequest(
  1458. IN PATMARP_VC pVc,
  1459. IN PATMARP_INTERFACE pInterface,
  1460. IN PAA_ARP_PKT_HEADER pArpHeader,
  1461. IN PAA_ARP_PKT_CONTENTS pArpContents
  1462. )
  1463. /*++
  1464. Routine Description:
  1465. Process an InARP Request. We send back an InARP Reply packet
  1466. with our address information.
  1467. In case this is a PVC we were trying to resolve, it is possible
  1468. that we are waiting for an InARP Reply ourselves, and the remote
  1469. station came up only now. To speed up the resolution process,
  1470. we restart the InARP Wait timeout so that it expires soon, causing
  1471. another InARP Request to be sent.
  1472. Arguments:
  1473. pVc - Pointer to VC on which the request arrived
  1474. pInterface - Pointer to ATMARP Interface containing this VC
  1475. pArpHeader - Pointer to ARP Header for this packet
  1476. pArpContents - Parsed contents of received ARP Request packet
  1477. Return Value:
  1478. None
  1479. --*/
  1480. {
  1481. //
  1482. // Temp locations used for swapping fields
  1483. //
  1484. UCHAR UNALIGNED * pAddress;
  1485. UCHAR Length;
  1486. //
  1487. // ARP Reply packet
  1488. //
  1489. PNDIS_PACKET pNdisPacket;
  1490. PUCHAR pArpPacket;
  1491. //
  1492. // Copy the Source address (IP+ATM) info into the Target address
  1493. // fields, and fill in the Source info fields with our IP+ATM info.
  1494. //
  1495. //
  1496. // IP Addresses:
  1497. //
  1498. pArpContents->pDstIPAddress = pArpContents->pSrcIPAddress;
  1499. pArpContents->pSrcIPAddress = (PUCHAR)&(pInterface->LocalIPAddress.IPAddress);
  1500. //
  1501. // ATM Numbers: set the target ATM number to the source ATM
  1502. // number, but set the source ATM number to the local ATM
  1503. // address.
  1504. //
  1505. pArpContents->pDstAtmNumber = pArpContents->pSrcAtmNumber;
  1506. pArpContents->DstAtmNumberTypeLen = pArpContents->SrcAtmNumberTypeLen;
  1507. pArpContents->pSrcAtmNumber = (pInterface->LocalAtmAddress.Address);
  1508. pArpContents->SrcAtmNumberTypeLen =
  1509. AA_PKT_ATM_ADDRESS_TO_TYPE_LEN(&(pInterface->LocalAtmAddress));
  1510. //
  1511. // ATM Subaddresses
  1512. //
  1513. pArpContents->pDstAtmSubaddress = pArpContents->pSrcAtmSubaddress;
  1514. pArpContents->DstAtmSubaddrTypeLen = pArpContents->SrcAtmSubaddrTypeLen;
  1515. pArpContents->pSrcAtmSubaddress = NULL;
  1516. pArpContents->SrcAtmSubaddrTypeLen = 0;
  1517. //
  1518. // Build the InARP Reply packet
  1519. //
  1520. pNdisPacket = AtmArpBuildARPPacket(
  1521. AA_PKT_OP_TYPE_INARP_REPLY,
  1522. pInterface,
  1523. &pArpPacket,
  1524. pArpContents
  1525. );
  1526. if (pNdisPacket != (PNDIS_PACKET)NULL)
  1527. {
  1528. //
  1529. // Before we send it off, check if this is a PVC being InARP'ed.
  1530. // If so, restart the InARP Wait timer so that it expires soon.
  1531. //
  1532. // It is also possible that this PVC was once resolved, but
  1533. // the remote end had gone away long enough for us to age out
  1534. // the corresponding IP entry. This packet might be due to the
  1535. // remote end coming back up. Start off an Inverse ARP operation
  1536. // to get our end of the PVC re-resolved.
  1537. //
  1538. AA_ACQUIRE_VC_LOCK(pVc);
  1539. if (AA_IS_FLAG_SET(
  1540. pVc->Flags,
  1541. AA_VC_TYPE_MASK,
  1542. AA_VC_TYPE_PVC) &&
  1543. (AA_IS_FLAG_SET(
  1544. pVc->Flags,
  1545. AA_VC_ARP_STATE_MASK,
  1546. AA_VC_INARP_IN_PROGRESS) ||
  1547. ((pVc->pAtmEntry != NULL_PATMARP_ATM_ENTRY) &&
  1548. (pVc->pAtmEntry->pIpEntryList == NULL_PATMARP_IP_ENTRY))))
  1549. {
  1550. BOOLEAN TimerWasRunning;
  1551. #if DBG
  1552. if ((pVc->pAtmEntry != NULL_PATMARP_ATM_ENTRY) &&
  1553. (pVc->pAtmEntry->pIpEntryList == NULL_PATMARP_IP_ENTRY))
  1554. {
  1555. AADEBUGP(AAD_LOUD,
  1556. ("InARPReq: PVC %p, AtmEntry %p has NULL IP Entry, will InARP again!\n",
  1557. pVc, pVc->pAtmEntry));
  1558. }
  1559. #endif
  1560. AA_SET_FLAG(pVc->Flags,
  1561. AA_VC_ARP_STATE_MASK,
  1562. AA_VC_INARP_IN_PROGRESS);
  1563. //
  1564. // Stop the currently running InARP Wait timer
  1565. //
  1566. TimerWasRunning = AtmArpStopTimer(&(pVc->Timer), pInterface);
  1567. //
  1568. // Start it again, to fire in 1 second
  1569. //
  1570. AtmArpStartTimer(
  1571. pInterface,
  1572. &(pVc->Timer),
  1573. AtmArpPVCInARPWaitTimeout,
  1574. 1,
  1575. (PVOID)pVc // Context
  1576. );
  1577. if (!TimerWasRunning)
  1578. {
  1579. AtmArpReferenceVc(pVc); // Timer reference
  1580. }
  1581. }
  1582. AtmArpSendPacketOnVc(pVc, pNdisPacket);
  1583. //
  1584. // The VC lock is released by SendPacketOnVc
  1585. //
  1586. }
  1587. }
  1588. VOID
  1589. AtmArpHandleInARPReply(
  1590. IN PATMARP_VC pVc,
  1591. IN PATMARP_INTERFACE pInterface,
  1592. IN PAA_ARP_PKT_HEADER pArpHeader,
  1593. IN PAA_ARP_PKT_CONTENTS pArpContents
  1594. )
  1595. /*++
  1596. Routine Description:
  1597. Process an InARP Reply packet, which should be a response to an InARP
  1598. Request we sent earlier.
  1599. There are two circumstances under which we send InARP Requests:
  1600. (1) To obtain the addresses at the other end of a PVC.
  1601. (2) In the process of revalidating an IP Address, if we aren't able
  1602. to contact the server AND a VC exists to this IP address, we send
  1603. an InARP Request to revalidate the IP entry.
  1604. In Case (1), we link the PVC to an ATM Address Entry. In Case (2),
  1605. we mark the IP entry for this VC as being "resolved", and start
  1606. data transfer to this IP address.
  1607. Arguments:
  1608. pVc - Pointer to ATMARP VC on which this packet arrived
  1609. pInterface - Pointer to ATMARP Interface
  1610. pArpHeader - Pointer to ARP Header for this packet
  1611. pArpContents - Parsed contents of received ARP Request packet
  1612. Return Value:
  1613. None
  1614. --*/
  1615. {
  1616. PATMARP_ATM_ENTRY pAtmEntry; // ATM entry to which this VC is linked
  1617. PATMARP_IP_ENTRY pIpEntry; // IP address entry
  1618. BOOLEAN TimerWasRunning;
  1619. PATMARP_VC * ppVc; // Used to unlink VC from unresolved list
  1620. ULONG rc; // Ref Count
  1621. PNDIS_PACKET PacketList; // Packets queued for sending
  1622. BOOLEAN IsBroadcast; // Is the IP Addr a broadcast/Class D addr?
  1623. if (pArpContents->pSrcIPAddress == NULL)
  1624. {
  1625. AADEBUGP(AAD_WARNING,
  1626. ("HandleInARPReply: IF %x, Null source address, discarding pkt\n", pInterface));
  1627. return;
  1628. }
  1629. AADEBUGP(AAD_INFO,
  1630. ("HandleInARPReply: IF %x, IP addr %d.%d.%d.%d\n",
  1631. pInterface,
  1632. ((PUCHAR)pArpContents->pSrcIPAddress)[0],
  1633. ((PUCHAR)pArpContents->pSrcIPAddress)[1],
  1634. ((PUCHAR)pArpContents->pSrcIPAddress)[2],
  1635. ((PUCHAR)pArpContents->pSrcIPAddress)[3]));
  1636. //
  1637. // Update our ARP cache with this information (regardless of whether
  1638. // this is a PVC or SVC).
  1639. //
  1640. pIpEntry = AtmArpLearnIPToAtm(
  1641. pInterface,
  1642. (PIP_ADDRESS)pArpContents->pSrcIPAddress,
  1643. pArpContents->SrcAtmNumberTypeLen,
  1644. pArpContents->pSrcAtmNumber,
  1645. pArpContents->SrcAtmSubaddrTypeLen,
  1646. pArpContents->pSrcAtmSubaddress,
  1647. FALSE // Not a static entry
  1648. );
  1649. //
  1650. // Acquire the locks that we need, in an ordered fashion...
  1651. //
  1652. AA_ACQUIRE_IF_LOCK(pInterface);
  1653. if (pIpEntry != NULL_PATMARP_IP_ENTRY)
  1654. {
  1655. AA_ACQUIRE_IE_LOCK_DPC(pIpEntry);
  1656. AA_ASSERT(AA_IE_IS_ALIVE(pIpEntry));
  1657. pAtmEntry = pIpEntry->pAtmEntry;
  1658. if (pAtmEntry != NULL_PATMARP_ATM_ENTRY)
  1659. {
  1660. AA_ACQUIRE_AE_LOCK_DPC(pAtmEntry);
  1661. }
  1662. }
  1663. else
  1664. {
  1665. pAtmEntry = NULL_PATMARP_ATM_ENTRY;
  1666. }
  1667. AA_ACQUIRE_VC_LOCK_DPC(pVc);
  1668. if (AA_IS_FLAG_SET(
  1669. pVc->Flags,
  1670. AA_VC_TYPE_MASK,
  1671. AA_VC_TYPE_PVC) &&
  1672. (pVc->pAtmEntry == NULL_PATMARP_ATM_ENTRY) )
  1673. {
  1674. //
  1675. // This is an unresolved PVC, whose remote address info
  1676. // we were trying to InARP for.
  1677. //
  1678. //
  1679. // Stop the InARP Wait timer running on this VC
  1680. //
  1681. TimerWasRunning = AtmArpStopTimer(&(pVc->Timer), pInterface);
  1682. AA_ASSERT(TimerWasRunning == TRUE);
  1683. if (TimerWasRunning)
  1684. {
  1685. rc = AtmArpDereferenceVc(pVc); // Timer reference
  1686. }
  1687. else
  1688. {
  1689. rc = pVc->RefCount;
  1690. }
  1691. //
  1692. // Do the rest only if the VC hasn't gone away.
  1693. //
  1694. if (rc != 0)
  1695. {
  1696. AA_SET_FLAG(
  1697. pVc->Flags,
  1698. AA_VC_ARP_STATE_MASK,
  1699. AA_VC_ARP_STATE_IDLE);
  1700. if (pAtmEntry != NULL_PATMARP_ATM_ENTRY)
  1701. {
  1702. //
  1703. // We are all set now. Take the VC out of the list of
  1704. // unresolved VCs on this Interface, and put it in the
  1705. // list of VCs attached to this ATM Entry.
  1706. //
  1707. // NOTE: we don't dereference the VC because we are just
  1708. // moving it from one list (Unresolved VCs) to another
  1709. // (ATM Entry's VC list).
  1710. //
  1711. ppVc = &(pInterface->pUnresolvedVcs);
  1712. while (*ppVc != pVc)
  1713. {
  1714. AA_ASSERT(*ppVc != NULL_PATMARP_VC);
  1715. ppVc = &((*ppVc)->pNextVc);
  1716. }
  1717. *ppVc = pVc->pNextVc;
  1718. AtmArpLinkVcToAtmEntry(pVc, pAtmEntry);
  1719. }
  1720. else
  1721. {
  1722. //
  1723. // No matching ATM Entry.
  1724. //
  1725. // We are really low on resources if we are here.
  1726. // Start the InARP Wait timer; when it fires, we'll try to
  1727. // send another InARP Request to resolve this VC.
  1728. //
  1729. AADEBUGP(AAD_FATAL,
  1730. ("HandleInARPReply: no matching ATM entry: pInterface %x, pVc %x, pIpEntry %x\n",
  1731. pInterface,
  1732. pVc,
  1733. pIpEntry));
  1734. AA_ASSERT(FALSE);
  1735. AtmArpStartTimer(
  1736. pInterface,
  1737. &(pVc->Timer),
  1738. AtmArpPVCInARPWaitTimeout,
  1739. pInterface->InARPWaitTimeout,
  1740. (PVOID)pVc // Context
  1741. );
  1742. AtmArpReferenceVc(pVc); // InARP Timer ref
  1743. }
  1744. AA_RELEASE_VC_LOCK_DPC(pVc);
  1745. }
  1746. else
  1747. {
  1748. //
  1749. // The VC went away while we were InARPing
  1750. //
  1751. }
  1752. //
  1753. // Release any locks that we still hold.
  1754. //
  1755. if (pIpEntry != NULL_PATMARP_IP_ENTRY)
  1756. {
  1757. if (pAtmEntry != NULL_PATMARP_ATM_ENTRY)
  1758. {
  1759. AA_RELEASE_AE_LOCK_DPC(pAtmEntry);
  1760. }
  1761. AA_RELEASE_IE_LOCK_DPC(pIpEntry);
  1762. }
  1763. AA_RELEASE_IF_LOCK(pInterface);
  1764. }
  1765. else
  1766. {
  1767. //
  1768. // Revalidating on a PVC/SVC: case (2) in Routine Description
  1769. //
  1770. AA_SET_FLAG(
  1771. pVc->Flags,
  1772. AA_VC_ARP_STATE_MASK,
  1773. AA_VC_ARP_STATE_IDLE);
  1774. //
  1775. // Stop the INARP timer, if it is running.
  1776. //
  1777. TimerWasRunning = AtmArpStopTimer(&pVc->Timer, pInterface);
  1778. if (TimerWasRunning)
  1779. {
  1780. rc = AtmArpDereferenceVc(pVc); // InARP reply: stop InARP timer
  1781. }
  1782. else
  1783. {
  1784. rc = pVc->RefCount;
  1785. }
  1786. if (rc != 0)
  1787. {
  1788. AA_RELEASE_VC_LOCK_DPC(pVc);
  1789. }
  1790. //
  1791. // Update the IP Entry we were revaldating.
  1792. //
  1793. if (pIpEntry != NULL_PATMARP_IP_ENTRY)
  1794. {
  1795. //
  1796. // Stop the InARP timer running here
  1797. //
  1798. TimerWasRunning = AtmArpStopTimer(&(pIpEntry->Timer), pInterface);
  1799. if (TimerWasRunning)
  1800. {
  1801. rc = AA_DEREF_IE(pIpEntry, IE_REFTYPE_TIMER); // timer ref
  1802. }
  1803. else
  1804. {
  1805. rc = pIpEntry->RefCount;
  1806. }
  1807. //
  1808. // Continue only if the IP Entry hasn't gone away.
  1809. //
  1810. if (rc > 0)
  1811. {
  1812. //
  1813. // Update its state
  1814. //
  1815. AA_SET_FLAG(
  1816. pIpEntry->Flags,
  1817. AA_IP_ENTRY_STATE_MASK,
  1818. AA_IP_ENTRY_RESOLVED
  1819. );
  1820. AADEBUGP(AAD_INFO,
  1821. ("InARP Reply: Revalidated pIpEntry 0x%x, IP Addr: %d.%d.%d.%d\n",
  1822. pIpEntry,
  1823. ((PUCHAR)(&(pIpEntry->IPAddress)))[0],
  1824. ((PUCHAR)(&(pIpEntry->IPAddress)))[1],
  1825. ((PUCHAR)(&(pIpEntry->IPAddress)))[2],
  1826. ((PUCHAR)(&(pIpEntry->IPAddress)))[3]
  1827. ));
  1828. AA_ASSERT(pAtmEntry != NULL_PATMARP_ATM_ENTRY);
  1829. //
  1830. // Start the Aging timer.
  1831. //
  1832. AtmArpStartTimer(
  1833. pInterface,
  1834. &(pIpEntry->Timer),
  1835. AtmArpIPEntryAgingTimeout,
  1836. pInterface->ARPEntryAgingTimeout,
  1837. (PVOID)pIpEntry
  1838. );
  1839. AA_REF_IE(pIpEntry, IE_REFTYPE_TIMER); // Timer ref
  1840. //
  1841. // Take out the list of pending packets on this Entry
  1842. //
  1843. PacketList = pIpEntry->PacketList;
  1844. pIpEntry->PacketList = (PNDIS_PACKET)NULL;
  1845. IsBroadcast = AA_IS_FLAG_SET(pIpEntry->Flags,
  1846. AA_IP_ENTRY_ADDR_TYPE_MASK,
  1847. AA_IP_ENTRY_ADDR_TYPE_NUCAST);
  1848. AA_RELEASE_AE_LOCK_DPC(pAtmEntry);
  1849. AA_RELEASE_IE_LOCK_DPC(pIpEntry);
  1850. AA_RELEASE_IF_LOCK(pInterface);
  1851. //
  1852. // Send out all these packets
  1853. //
  1854. AtmArpSendPacketListOnAtmEntry(
  1855. pInterface,
  1856. pAtmEntry,
  1857. PacketList,
  1858. IsBroadcast
  1859. );
  1860. }
  1861. else
  1862. {
  1863. //
  1864. // the IP Entry is gone
  1865. //
  1866. AA_RELEASE_AE_LOCK_DPC(pAtmEntry);
  1867. AA_RELEASE_IF_LOCK(pInterface);
  1868. }
  1869. }
  1870. else
  1871. {
  1872. //
  1873. // No matching IP Entry
  1874. //
  1875. AA_RELEASE_IF_LOCK(pInterface);
  1876. }
  1877. }
  1878. return;
  1879. }