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.

1200 lines
34 KiB

  1. /*++
  2. Copyright (c) 1998-1999 Microsoft Corporation
  3. Module Name:
  4. arp.c
  5. Abstract:
  6. ARP1394 ARP request/response handling code.
  7. Revision History:
  8. Who When What
  9. -------- -------- ----------------------------------------------
  10. josephj 03-28-99 Created
  11. Notes:
  12. --*/
  13. #include <precomp.h>
  14. //
  15. // File-specific debugging defaults.
  16. //
  17. #define TM_CURRENT TM_ARP
  18. // #define ARP_DEFAULT_MAXREC 0xD
  19. #define ARP_DEFAULT_MAXREC 0x8
  20. #define LOGSTATS_SuccessfulArpQueries(_pIF) \
  21. NdisInterlockedIncrement(&((_pIF)->stats.arpcache.SuccessfulQueries))
  22. #define LOGSTATS_FailedArpQueried(_pIF) \
  23. NdisInterlockedIncrement(&((_pIF)->stats.arpcache.FailedQueries))
  24. #define LOGSTATS_TotalQueries(_pIF) \
  25. NdisInterlockedIncrement(&((_pIF)->stats.arpcache.TotalQueries))
  26. #define LOGSTATS_TotalArpResponses(_pIF) \
  27. NdisInterlockedIncrement(&((_pIF)->stats.arpcache.TotalResponses))
  28. //=========================================================================
  29. // L O C A L P R O T O T Y P E S
  30. //=========================================================================
  31. NDIS_STATUS
  32. arpSendArpRequest(
  33. PARPCB_REMOTE_IP pRemoteIp,
  34. PRM_STACK_RECORD pSR
  35. );
  36. VOID
  37. arpProcessArpRequest(
  38. PARP1394_INTERFACE pIF, // NOLOCKIN NOLOCKOUT
  39. PIP1394_ARP_PKT_INFO pPktInfo,
  40. PRM_STACK_RECORD pSR
  41. );
  42. VOID
  43. arpProcessArpResponse(
  44. PARP1394_INTERFACE pIF, // NOLOCKIN NOLOCKOUT
  45. PIP1394_ARP_PKT_INFO pPktInfo,
  46. PRM_STACK_RECORD pSR
  47. );
  48. VOID
  49. arpTryAbortResolutionTask(
  50. PARPCB_REMOTE_IP pRemoteIp,
  51. PRM_STACK_RECORD pSR
  52. );
  53. NDIS_STATUS
  54. arpParseArpPkt(
  55. IN PIP1394_ARP_PKT pArpPkt,
  56. IN UINT cbBufferSize,
  57. OUT PIP1394_ARP_PKT_INFO pPktInfo
  58. )
  59. /*++
  60. Routine Description:
  61. Parse the contents of IP/1394 ARP packet data starting at
  62. pArpPkt. Place the results into pPktInfo.
  63. Arguments:
  64. pArpPkt - Contains the unaligned contents of an ip/1394 ARP Pkt.
  65. pPktInfo - Unitialized structure to be filled with the parsed contents of the
  66. pkt.
  67. Return Value:
  68. NDIS_STATUS_FAILURE if the parse failed (typically because of invalid pkt
  69. contents.)
  70. NDIS_STATUS_SUCCESS on successful parsing.
  71. --*/
  72. {
  73. ENTER("arpParseArpPkt", 0x20098dc0)
  74. NDIS_STATUS Status;
  75. DBGSTMT(CHAR *szError = "General failure";)
  76. Status = NDIS_STATUS_FAILURE;
  77. do
  78. {
  79. UINT SenderMaxRec;
  80. UINT OpCode;
  81. // Verify length.
  82. //
  83. if (cbBufferSize < sizeof(*pArpPkt))
  84. {
  85. DBGSTMT(szError = "pkt size too small";)
  86. break;
  87. }
  88. // Verify constant fields.
  89. //
  90. #if 0 // Reserved is no "NodeId, which contains the nodeid of the sending
  91. // node, if known (0 otherwise).
  92. if (pArpPkt->header.Reserved != 0)
  93. {
  94. DBGSTMT(szError = "header.Reserved!=0";)
  95. break;
  96. }
  97. #endif // 0
  98. if (N2H_USHORT(pArpPkt->header.EtherType) != NIC1394_ETHERTYPE_ARP)
  99. {
  100. DBGSTMT(szError = "header.EtherType!=ARP";)
  101. break;
  102. }
  103. if (N2H_USHORT(pArpPkt->hardware_type) != IP1394_HARDWARE_TYPE)
  104. {
  105. DBGSTMT(szError = "Invalid hardware_type";)
  106. break;
  107. }
  108. if (N2H_USHORT(pArpPkt->protocol_type) != IP1394_PROTOCOL_TYPE)
  109. {
  110. DBGSTMT(szError = "Invalid protocol_type";)
  111. break;
  112. }
  113. if (pArpPkt->hw_addr_len != IP1394_HW_ADDR_LEN)
  114. {
  115. DBGSTMT(szError = "Invalid hw_addr_len";)
  116. break;
  117. }
  118. if (pArpPkt->IP_addr_len != sizeof(ULONG))
  119. {
  120. DBGSTMT(szError = "Invalid IP_addr_len";)
  121. break;
  122. }
  123. // Opcode
  124. //
  125. {
  126. OpCode = N2H_USHORT(pArpPkt->opcode);
  127. if ( OpCode != IP1394_ARP_REQUEST
  128. && OpCode != IP1394_ARP_RESPONSE)
  129. {
  130. DBGSTMT(szError = "Invalid opcode";)
  131. break;
  132. }
  133. }
  134. // Max send block size...
  135. //
  136. {
  137. UINT maxrec = pArpPkt->sender_maxrec;
  138. if (IP1394_IS_VALID_MAXREC(maxrec))
  139. {
  140. SenderMaxRec = maxrec;
  141. }
  142. else
  143. {
  144. DBGSTMT(szError = "Invalid sender_maxrec";)
  145. break;
  146. }
  147. }
  148. //
  149. // Pkt appears valid, let's fill out the parsed information....
  150. //
  151. ARP_ZEROSTRUCT(pPktInfo);
  152. pPktInfo->OpCode = OpCode;
  153. pPktInfo->SenderMaxRec = SenderMaxRec;
  154. // Speed code...
  155. //
  156. {
  157. UINT SenderMaxSpeedCode;
  158. //
  159. // We rely on the fact that the RFC speed code constants
  160. // (IP1394_SSPD_*) are identical to the corresponding
  161. // constants defined in 1394.h (SCODE_*). Let's ensure this...
  162. //
  163. #if (IP1394_SSPD_S100 != SCODE_100_RATE)
  164. #error "RFC Speed code out of sync with 1394.h"
  165. #endif
  166. #if (IP1394_SSPD_S200 != SCODE_200_RATE)
  167. #error "RFC Speed code out of sync with 1394.h"
  168. #endif
  169. #if (IP1394_SSPD_S400 != SCODE_400_RATE)
  170. #error "RFC Speed code out of sync with 1394.h"
  171. #endif
  172. #if (IP1394_SSPD_S800 != SCODE_800_RATE)
  173. #error "RFC Speed code out of sync with 1394.h"
  174. #endif
  175. #if (IP1394_SSPD_S1600 != SCODE_1600_RATE)
  176. #error "RFC Speed code out of sync with 1394.h"
  177. #endif
  178. #if (IP1394_SSPD_S3200 != SCODE_3200_RATE)
  179. #error "RFC Speed code out of sync with 1394.h"
  180. #endif
  181. SenderMaxSpeedCode = pArpPkt->sspd;
  182. if (SenderMaxSpeedCode > SCODE_3200_RATE)
  183. {
  184. //
  185. // This is either a bad value, or a rate higher than we know about.
  186. // We can't distinguish between the two, so we just set the speed to
  187. // the highest we know about.
  188. // TODO: 3/28/99 JosephJ not sure if this is the correct
  189. // behaviour -- maybe we should fail -- I'll be asking the
  190. // working group to rule on this shortly...
  191. //
  192. SenderMaxSpeedCode = SCODE_3200_RATE;
  193. }
  194. pPktInfo->SenderMaxSpeedCode = SenderMaxSpeedCode;
  195. }
  196. // Unique ID -- we also need to swap DWORDS to convert from network byte
  197. // order.
  198. //
  199. {
  200. PUINT puSrc = (PUINT) & (pArpPkt->sender_unique_ID);
  201. PUINT puDest = (PUINT) & (pPktInfo->SenderHwAddr.UniqueID);
  202. // pPktInfo->SenderHwAddr.UniqueID = pArpPkt->sender_unique_ID;
  203. puDest[0] = puSrc[1];
  204. puDest[1] = puSrc[0];
  205. }
  206. pPktInfo->SenderHwAddr.Off_Low =H2N_ULONG(pArpPkt->sender_unicast_FIFO_lo);
  207. pPktInfo->SenderHwAddr.Off_High =H2N_USHORT(pArpPkt->sender_unicast_FIFO_hi);
  208. // These remain network byte order...
  209. //
  210. pPktInfo->SenderIpAddress = (IP_ADDRESS) pArpPkt->sender_IP_address;
  211. pPktInfo->TargetIpAddress = (IP_ADDRESS) pArpPkt->target_IP_address;
  212. // Extract the Src Node Address
  213. //
  214. {
  215. PNDIS1394_UNFRAGMENTED_HEADER pHeader = (PNDIS1394_UNFRAGMENTED_HEADER)&pArpPkt->header;
  216. if (pHeader->u1.fHeaderHasSourceAddress == TRUE)
  217. {
  218. pPktInfo->SourceNodeAdddress = pHeader->u1.SourceAddress;
  219. pPktInfo->fPktHasNodeAddress = TRUE;
  220. }
  221. }
  222. Status = NDIS_STATUS_SUCCESS;
  223. } while (FALSE);
  224. if (FAIL(Status))
  225. {
  226. TR_INFO(("Bad arp pkt data at 0x%p (%s)\n", pArpPkt, szError));
  227. }
  228. else
  229. {
  230. TR_WARN(("Received ARP PKT. UID=0x%I64x FIFO=0x%04lx:0x%08lx OP=%lu SIP=0x%04lx TIP=0x%04lx.\n",
  231. pPktInfo->SenderHwAddr.UniqueID,
  232. pPktInfo->SenderHwAddr.Off_High,
  233. pPktInfo->SenderHwAddr.Off_Low,
  234. pPktInfo->OpCode,
  235. pPktInfo->SenderIpAddress,
  236. pPktInfo->TargetIpAddress
  237. ));
  238. }
  239. EXIT()
  240. return Status;
  241. }
  242. VOID
  243. arpPrepareArpPkt(
  244. IN PIP1394_ARP_PKT_INFO pPktInfo,
  245. // IN UINT SenderMaxRec,
  246. OUT PIP1394_ARP_PKT pArpPkt
  247. )
  248. /*++
  249. Routine Description:
  250. Use information in pArpPktInfo to prepare an arp packet starting at
  251. pvArpPkt.
  252. Arguments:
  253. pPktInfo - Parsed version of the arp request/response packet.
  254. // SenderMaxRec - max_rec value of the local host
  255. pArpPkt - unitialized memory in which to store the packet contents.
  256. This memory must have a min size of sizeof(*pArpPkt).
  257. --*/
  258. {
  259. // UINT SenderMaxRec;
  260. UINT OpCode;
  261. ARP_ZEROSTRUCT(pArpPkt);
  262. pArpPkt->header.EtherType = H2N_USHORT(NIC1394_ETHERTYPE_ARP);
  263. pArpPkt->hardware_type = H2N_USHORT(IP1394_HARDWARE_TYPE);
  264. pArpPkt->protocol_type = H2N_USHORT(IP1394_PROTOCOL_TYPE);
  265. pArpPkt->hw_addr_len = (UCHAR) IP1394_HW_ADDR_LEN;
  266. pArpPkt->IP_addr_len = (UCHAR) sizeof(ULONG);
  267. pArpPkt->opcode = H2N_USHORT(pPktInfo->OpCode);
  268. pArpPkt->sender_maxrec = (UCHAR) pPktInfo->SenderMaxRec;
  269. //
  270. // We rely on the fact that the RFC speed code constants
  271. // (IP1394_SSPD_*) are identical to the corresponding
  272. // constants defined in 1394.h (SCODE_*). We have a bunch of compiler-time
  273. // checks to ensure this (see arpParseArpPkt(...)).
  274. //
  275. pArpPkt->sspd = (UCHAR) pPktInfo->SenderMaxSpeedCode;
  276. // Unique ID -- we also need to swap DWORDS to convert to network byte order.
  277. //
  278. {
  279. PUINT puSrc = (PUINT) & (pPktInfo->SenderHwAddr.UniqueID);
  280. PUINT puDest = (PUINT) & (pArpPkt->sender_unique_ID);
  281. // pArpPkt->sender_unique_ID = pPktInfo->SenderHwAddr.UniqueID;
  282. puDest[0] = puSrc[1];
  283. puDest[1] = puSrc[0];
  284. }
  285. pArpPkt->sender_unicast_FIFO_lo = N2H_ULONG(pPktInfo->SenderHwAddr.Off_Low);
  286. pArpPkt->sender_unicast_FIFO_hi = N2H_USHORT(pPktInfo->SenderHwAddr.Off_High);
  287. // These are already in network byte order...
  288. //
  289. pArpPkt->sender_IP_address = (ULONG) pPktInfo->SenderIpAddress;
  290. pArpPkt->target_IP_address = (ULONG) pPktInfo->TargetIpAddress;
  291. }
  292. NDIS_STATUS
  293. arpPrepareArpResponse(
  294. IN PARP1394_INTERFACE pIF, // NOLOCKIN NOLOCKOUT
  295. IN PIP1394_ARP_PKT_INFO pArpRequest,
  296. OUT PIP1394_ARP_PKT_INFO pArpResponse,
  297. IN PRM_STACK_RECORD pSR
  298. )
  299. /*++
  300. Routine Description:
  301. If it makes sense to do so, prepare (in pArpResponse) an arp response to
  302. the arp request in pArpRequest.
  303. Arguments:
  304. pIF - Interface control block.
  305. pArpRequest - Parsed version of the ARP request packet.
  306. pArpResponse - Uninitialized memory to hold the parsed version of the
  307. ARP response packet (if there is a response).
  308. Return Value:
  309. NDIS_STATUS_SUCCESS if the response was filled out.
  310. Some NDIS error code otherwise.
  311. --*/
  312. {
  313. ENTER("arpPrepareArpResponse", 0x0d7e0e60)
  314. NDIS_STATUS Status;
  315. PARPCB_LOCAL_IP pLocalIp;
  316. Status = NDIS_STATUS_FAILURE;
  317. pLocalIp = NULL;
  318. RM_ASSERT_OBJUNLOCKED(&pIF->Hdr, pSR);
  319. do
  320. {
  321. IP_ADDRESS TargetIpAddress = pArpRequest->TargetIpAddress;
  322. // Lookup local IP
  323. //
  324. Status = RM_LOOKUP_AND_LOCK_OBJECT_IN_GROUP(
  325. &pIF->LocalIpGroup,
  326. (PVOID) ULongToPtr (TargetIpAddress),
  327. (RM_OBJECT_HEADER**) &pLocalIp,
  328. pSR
  329. );
  330. if (FAIL(Status))
  331. {
  332. pLocalIp = NULL;
  333. break;
  334. }
  335. Status = NDIS_STATUS_FAILURE;
  336. RM_DBG_ASSERT_LOCKED(&pLocalIp->Hdr, pSR);
  337. ASSERT(TargetIpAddress == pLocalIp->IpAddress);
  338. if (ARP_LOCAL_IP_IS_UNLOADING(pLocalIp)) break;
  339. //
  340. // If the local IP is non-unicast, don't respond!
  341. //
  342. if (pLocalIp->IpAddressType != LLIP_ADDR_LOCAL)
  343. {
  344. TR_WARN(("Ignoring arp request for non-unicast address 0x%08lx.\n",
  345. TargetIpAddress));
  346. break;
  347. }
  348. //
  349. // We do serve the target IP address. Let's fill out pArpResponse...
  350. //
  351. ARP_ZEROSTRUCT(pArpResponse);
  352. pArpResponse->OpCode = IP1394_ARP_RESPONSE;
  353. pArpResponse->SenderIpAddress = TargetIpAddress;
  354. // This field is unused in the response, but we fill it anyway..
  355. // 11/19/1999 From Kaz Honda of Sony: we should fill it with destination
  356. // IP address (i.e. the ip address of the sender of the arp request).
  357. // because that is analogous to what ethernet arp does. Note that
  358. // the ip/1394 rfc says that the field should be ignored, but we do
  359. // this anyway.
  360. //
  361. // pArpResponse->TargetIpAddress = TargetIpAddress;
  362. pArpResponse->TargetIpAddress = pArpRequest->SenderIpAddress;
  363. // Fill out adapter info..
  364. //
  365. {
  366. PARP1394_ADAPTER pAdapter = (PARP1394_ADAPTER) RM_PARENT_OBJECT(pIF);
  367. pArpResponse->SenderHwAddr.UniqueID = pAdapter->info.LocalUniqueID;
  368. pArpResponse->SenderHwAddr.Off_Low = pIF->recvinfo.offset.Off_Low;
  369. pArpResponse->SenderHwAddr.Off_High = pIF->recvinfo.offset.Off_High;
  370. pArpResponse->SenderMaxRec= pAdapter->info.MaxRec;
  371. pArpResponse->SenderMaxSpeedCode= pAdapter->info.MaxSpeedCode;
  372. }
  373. Status = NDIS_STATUS_SUCCESS;
  374. } while (FALSE);
  375. if (pLocalIp != NULL)
  376. {
  377. UNLOCKOBJ(pLocalIp, pSR);
  378. RmTmpDereferenceObject(&pLocalIp->Hdr, pSR);
  379. }
  380. RM_ASSERT_OBJUNLOCKED(&pIF->Hdr, pSR);
  381. EXIT()
  382. return Status;
  383. }
  384. NDIS_STATUS
  385. arpTaskResolveIpAddress(
  386. IN struct _RM_TASK * pTask,
  387. IN RM_TASK_OPERATION Code,
  388. IN UINT_PTR UserParam,
  389. IN PRM_STACK_RECORD pSR
  390. )
  391. {
  392. NDIS_STATUS Status;
  393. PARPCB_REMOTE_IP pRemoteIp;
  394. PTASK_RESOLVE_IP_ADDRESS pResolutionTask;
  395. enum
  396. {
  397. PEND_ResponseTimeout
  398. };
  399. ENTER("TaskResolveIpAddress", 0x3dd4b434)
  400. Status = NDIS_STATUS_FAILURE;
  401. pRemoteIp = (PARPCB_REMOTE_IP) RM_PARENT_OBJECT(pTask);
  402. pResolutionTask = (PTASK_RESOLVE_IP_ADDRESS) pTask;
  403. switch(Code)
  404. {
  405. case RM_TASKOP_START:
  406. {
  407. DBGMARK(0x7de307cc);
  408. //
  409. // There should NOT be another resolution task running
  410. // on pRemoteIp. Why? Because a resolution task is ONLY
  411. // started in the context of a send-pkts task, and there can be
  412. // ONLY one active send-pkts task on pRemoteIp at any one time.
  413. //
  414. LOCKOBJ(pRemoteIp, pSR);
  415. if (pRemoteIp->pResolutionTask != NULL)
  416. {
  417. ASSERT(!"pRemoteIp->pResolutionTask != NULL");
  418. UNLOCKOBJ(pRemoteIp, pSR);
  419. Status = NDIS_STATUS_FAILURE;
  420. break;
  421. }
  422. //
  423. // Make ourselves the official resolution task.
  424. //
  425. // Although it's tempting to put pTask as entity1 and
  426. // pTask->Hdr.szDescption as entity2 below, we specify NULL for both so
  427. // that we can be sure that ONLY one resolution task can be active at any
  428. // one time. TODO: modify addassoc semantics to get both advantages.
  429. //
  430. DBG_ADDASSOC(
  431. &pRemoteIp->Hdr,
  432. NULL, // Entity1
  433. NULL, // Entity2
  434. ARPASSOC_RESOLUTION_IF_TASK,
  435. " Resolution task\n",
  436. pSR
  437. );
  438. pRemoteIp->pResolutionTask = pTask;
  439. pResolutionTask->RetriesLeft = 3;
  440. // Now we do a fake suspend/resume so we move on to the next stage.
  441. //
  442. RmSuspendTask(pTask, PEND_ResponseTimeout, pSR);
  443. UNLOCKOBJ(pRemoteIp, pSR);
  444. RmResumeTask(pTask, NDIS_STATUS_SUCCESS, pSR);
  445. Status = NDIS_STATUS_PENDING;
  446. }
  447. break;
  448. case RM_TASKOP_PENDCOMPLETE:
  449. {
  450. switch(RM_PEND_CODE(pTask))
  451. {
  452. case PEND_ResponseTimeout:
  453. {
  454. DBGMARK(0x3b5562e6);
  455. LOCKOBJ(pRemoteIp, pSR);
  456. //
  457. // Let's see if the address is resolved and/or we're
  458. // to abort the resolution task because perhaps pRemoteIp
  459. // is going away.
  460. //
  461. if (pRemoteIp->pUnloadTask != NULL)
  462. {
  463. OBJLOG0(
  464. pRemoteIp,
  465. "Aborting address resolution because we're unloading.\n"
  466. );
  467. Status = NDIS_STATUS_FAILURE;
  468. UNLOCKOBJ(pRemoteIp, pSR);
  469. break;
  470. }
  471. if (pRemoteIp->pDest != NULL)
  472. {
  473. LOGSTATS_SuccessfulArpQueries(IF_FROM_REMOTEIP(pRemoteIp));
  474. OBJLOG1(
  475. pRemoteIp,
  476. "Resolved Ip Address; pDest = 0x%p\n",
  477. pRemoteIp->pDest
  478. );
  479. ASSERT(
  480. CHECK_REMOTEIP_RESOLVE_STATE(pRemoteIp, ARPREMOTEIP_RESOLVED)
  481. );
  482. Status = NDIS_STATUS_SUCCESS;
  483. UNLOCKOBJ(pRemoteIp, pSR);
  484. break;
  485. }
  486. //
  487. // We need to resolve this address..
  488. //
  489. if (pResolutionTask->RetriesLeft)
  490. {
  491. pResolutionTask->RetriesLeft--;
  492. // Build an ARP request and send it out.
  493. //
  494. Status = arpSendArpRequest(pRemoteIp, pSR);
  495. // pRemoteIp's lock is released by the above call.
  496. //
  497. RM_ASSERT_OBJUNLOCKED(&pRemoteIp->Hdr, pSR);
  498. //
  499. // We ignore the return status of the above call -- so
  500. // whether or not the request could be sent out,
  501. // we suspend this task for resolution-timeout seconds.
  502. //
  503. RmSuspendTask(pTask, PEND_ResponseTimeout, pSR);
  504. RmResumeTaskDelayed(
  505. pTask,
  506. 0,
  507. ARP1394_ADDRESS_RESOLUTION_TIMEOUT,
  508. &pResolutionTask->Timer,
  509. pSR
  510. );
  511. Status = NDIS_STATUS_PENDING;
  512. }
  513. else
  514. {
  515. LOGSTATS_FailedArpQueried(IF_FROM_REMOTEIP(pRemoteIp));
  516. // Oops -- couldn't resolve this address.
  517. //
  518. OBJLOG1(
  519. pRemoteIp,
  520. "Timed out trying to resolve address 0x%08lx\n",
  521. pRemoteIp->IpAddress
  522. );
  523. UNLOCKOBJ(pRemoteIp, pSR);
  524. Status = NDIS_STATUS_FAILURE;
  525. }
  526. }
  527. break;
  528. }
  529. }
  530. break;
  531. case RM_TASKOP_END:
  532. {
  533. //
  534. // We are done with address resolution. Clear ourselves
  535. // as the official address resolution task of pRemoteIp.
  536. //
  537. LOCKOBJ(pRemoteIp, pSR);
  538. DBGMARK(0x6bd6d27a);
  539. if (pRemoteIp->pResolutionTask != pTask)
  540. {
  541. ASSERT(FALSE);
  542. }
  543. else
  544. {
  545. // Delete the association added when setting the resolution task
  546. //
  547. DBG_DELASSOC(
  548. &pRemoteIp->Hdr,
  549. NULL,
  550. NULL,
  551. ARPASSOC_RESOLUTION_IF_TASK,
  552. pSR
  553. );
  554. pRemoteIp->pResolutionTask = NULL;
  555. }
  556. UNLOCKOBJ(pRemoteIp, pSR);
  557. // Propagate the status code
  558. //
  559. Status = (NDIS_STATUS) UserParam;
  560. }
  561. break;
  562. default:
  563. {
  564. ASSERTEX(!"Unknown task op", pTask);
  565. }
  566. break;
  567. } // switch (Code)
  568. RM_ASSERT_NOLOCKS(pSR);
  569. EXIT()
  570. return Status;
  571. }
  572. NDIS_STATUS
  573. arpSendArpRequest(
  574. PARPCB_REMOTE_IP pRemoteIp, // LOCKIN NOLOCKOUT
  575. PRM_STACK_RECORD pSR
  576. )
  577. {
  578. NDIS_STATUS Status;
  579. PARP1394_INTERFACE pIF;
  580. PNDIS_PACKET pNdisPacket;
  581. PIP1394_ARP_PKT pPktData;
  582. IPAddr TargetIpAddress = 0;
  583. ENTER("arpSendArpRequest", 0xcecfc632)
  584. RM_ASSERT_OBJLOCKED(&pRemoteIp->Hdr, pSR);
  585. pIF = (PARP1394_INTERFACE) RM_PARENT_OBJECT(pRemoteIp);
  586. DBGMARK(0xb90e9ffc);
  587. Status = arpAllocateControlPacket(
  588. pIF,
  589. sizeof(IP1394_ARP_PKT),
  590. ARP1394_PACKET_FLAGS_ARP,
  591. &pNdisPacket,
  592. &pPktData,
  593. pSR
  594. );
  595. if (FAIL(Status))
  596. {
  597. UNLOCKOBJ(pRemoteIp, pSR);
  598. }
  599. else
  600. {
  601. IP1394_ARP_PKT_INFO PktInfo;
  602. PARP1394_ADAPTER pAdapter = (PARP1394_ADAPTER) RM_PARENT_OBJECT(pIF);
  603. //
  604. // If we are running in bridge the Target Ip Address is stored in
  605. // the BridgeTargetIpAddress Field. Otherwise it is in the Key.
  606. //
  607. ASSERT (pRemoteIp->IpAddress != 0);
  608. // Prepare the packet.
  609. //
  610. PktInfo.SenderHwAddr.UniqueID = pAdapter->info.LocalUniqueID;
  611. PktInfo.SenderHwAddr.Off_Low = pIF->recvinfo.offset.Off_Low;
  612. PktInfo.SenderHwAddr.Off_High = pIF->recvinfo.offset.Off_High;
  613. PktInfo.OpCode = IP1394_ARP_REQUEST;
  614. PktInfo.SenderMaxRec = pAdapter->info.MaxRec;
  615. PktInfo.SenderMaxSpeedCode = pAdapter->info.MaxSpeedCode;
  616. PktInfo.TargetIpAddress = pRemoteIp->IpAddress;
  617. PktInfo.SenderIpAddress = pIF->ip.DefaultLocalAddress;
  618. arpPrepareArpPkt(
  619. &PktInfo,
  620. // ARP_DEFAULT_MAXREC, // SenderMaxRec TODO
  621. pPktData
  622. );
  623. RmTmpReferenceObject(&pIF->Hdr, pSR);
  624. UNLOCKOBJ(pRemoteIp, pSR);
  625. RM_ASSERT_NOLOCKS(pSR);
  626. TR_WARN(("Attempting to send ARP Req PKT. UID=0x%I64x FIFO=0x%04lx:0x%08lx OP=%lu SIP=0x%04lx TIP=0x%04lx.\n",
  627. PktInfo.SenderHwAddr.UniqueID,
  628. PktInfo.SenderHwAddr.Off_High,
  629. PktInfo.SenderHwAddr.Off_Low,
  630. PktInfo.OpCode,
  631. PktInfo.SenderIpAddress,
  632. PktInfo.TargetIpAddress
  633. ));
  634. LOGSTATS_TotalQueries(pIF);
  635. ARP_FASTREADLOCK_IF_SEND_LOCK(pIF);
  636. // Actually send the packet (this will silently fail and free the pkt
  637. // if we're not in a position to send the pkt.)
  638. //
  639. arpSendControlPkt(
  640. pIF, // LOCKIN NOLOCKOUT (IF send lk)
  641. pNdisPacket,
  642. pIF->pBroadcastDest,
  643. pSR
  644. );
  645. RM_ASSERT_NOLOCKS(pSR);
  646. RmTmpDereferenceObject(&pIF->Hdr, pSR);
  647. }
  648. EXIT()
  649. return Status;
  650. }
  651. VOID
  652. arpSendControlPkt(
  653. IN ARP1394_INTERFACE * pIF, // LOCKIN NOLOCKOUT (IF send lk)
  654. IN PNDIS_PACKET pNdisPacket,
  655. PARPCB_DEST pDest,
  656. IN PRM_STACK_RECORD pSR
  657. )
  658. /*++
  659. Routine Description:
  660. Send a packet on the broadcast channel.
  661. Arguments:
  662. pIF - Our interface object
  663. pNdisPacket - Packet to send
  664. --*/
  665. {
  666. NDIS_STATUS Status;
  667. MYBOOL fRet;
  668. ENTER("arpSendControlPkt", 0x2debf9b7)
  669. DBGMARK(0xe6823818);
  670. //
  671. // If we can't send now, we fail.
  672. //
  673. if (pDest==NULL || !ARP_CAN_SEND_ON_DEST(pDest))
  674. {
  675. ARP_FASTUNLOCK_IF_SEND_LOCK(pIF);
  676. TR_WARN(("Couldn't send control pkt 0x%p.\n", pNdisPacket));
  677. arpFreeControlPacket(
  678. pIF,
  679. pNdisPacket,
  680. pSR
  681. );
  682. return; // EARLY RETURN
  683. }
  684. arpRefSendPkt( pNdisPacket, pDest);
  685. // Release the IF send lock.
  686. //
  687. ARP_FASTUNLOCK_IF_SEND_LOCK(pIF);
  688. // Actually send the packet
  689. //
  690. #if ARPDBG_FAKE_SEND
  691. arpDbgFakeNdisCoSendPackets(
  692. pDest->VcHdr.NdisVcHandle,
  693. &pNdisPacket,
  694. 1,
  695. &pDest->Hdr,
  696. &pDest->VcHdr
  697. );
  698. #else // !ARPDBG_FAKE_SEND
  699. NdisCoSendPackets(
  700. pDest->VcHdr.NdisVcHandle,
  701. &pNdisPacket,
  702. 1
  703. );
  704. #endif // !ARPDBG_FAKE_SEND
  705. EXIT()
  706. }
  707. VOID
  708. arpProcessArpPkt(
  709. PARP1394_INTERFACE pIF, // NOLOCKIN NOLOCKOUT
  710. PIP1394_ARP_PKT pArpPkt,
  711. UINT cbBufferSize
  712. )
  713. /*++
  714. Process an arp packet (request OR response) from the 1394 bus.
  715. --*/
  716. {
  717. NDIS_STATUS Status;
  718. IP1394_ARP_PKT_INFO PktInfo;
  719. ENTER("arpProcessArpPkt", 0x6e81a8fa)
  720. RM_DECLARE_STACK_RECORD(sr)
  721. DBGMARK(0x03f6830e);
  722. Status = arpParseArpPkt(
  723. pArpPkt,
  724. cbBufferSize,
  725. &PktInfo
  726. );
  727. if (!FAIL(Status))
  728. {
  729. if (PktInfo.OpCode == IP1394_ARP_REQUEST)
  730. {
  731. arpProcessArpRequest(pIF, &PktInfo, &sr);
  732. }
  733. else
  734. {
  735. ASSERT(PktInfo.OpCode == IP1394_ARP_RESPONSE);
  736. arpProcessArpResponse(pIF, &PktInfo, &sr);
  737. }
  738. }
  739. RM_ASSERT_CLEAR(&sr);
  740. EXIT()
  741. }
  742. VOID
  743. arpProcessArpRequest(
  744. PARP1394_INTERFACE pIF, // NOLOCKIN NOLOCKOUT
  745. PIP1394_ARP_PKT_INFO pPktInfo,
  746. PRM_STACK_RECORD pSR
  747. )
  748. {
  749. IP1394_ARP_PKT_INFO ResponsePktInfo;
  750. NDIS_STATUS Status;
  751. ENTER("arpProcessArpRequest", 0xd33fa61d)
  752. RM_ASSERT_NOLOCKS(pSR);
  753. // pStatsCmd->TotalResponses = pIF->stats.arpcache.TotalResponses;
  754. // pStatsCmd->TotalLookups = pIF->stats.arpcache.TotalLookups;
  755. Status = arpPrepareArpResponse(
  756. pIF, // NOLOCKIN NOLOCKOUT
  757. pPktInfo,
  758. &ResponsePktInfo,
  759. pSR
  760. );
  761. if (!FAIL(Status))
  762. {
  763. ARP_DEST_PARAMS DestParams;
  764. PNDIS_PACKET pNdisPacket;
  765. PIP1394_ARP_PKT pPktData;
  766. ARP_ZEROSTRUCT(&DestParams);
  767. DestParams.HwAddr.AddressType = NIC1394AddressType_FIFO;
  768. DestParams.HwAddr.FifoAddress = pPktInfo->SenderHwAddr; // Struct copy
  769. //
  770. // Update our arp cache with information from the sender's portion of
  771. // the arp request.
  772. //
  773. arpUpdateArpCache(
  774. pIF,
  775. pPktInfo->SenderIpAddress, // Remote IP Address,
  776. NULL, // Sender's Ethernet Address
  777. &DestParams, // Remote Destination HW Address
  778. TRUE, // If required, create an entry for this.,
  779. pSR
  780. );
  781. //
  782. // Let's send the response!
  783. //
  784. Status = arpAllocateControlPacket(
  785. pIF,
  786. sizeof(IP1394_ARP_PKT),
  787. ARP1394_PACKET_FLAGS_ARP,
  788. &pNdisPacket,
  789. &pPktData,
  790. pSR
  791. );
  792. if (!FAIL(Status))
  793. {
  794. LOGSTATS_TotalArpResponses(pIF);
  795. // Prepare the packet.
  796. //
  797. arpPrepareArpPkt(
  798. &ResponsePktInfo,
  799. // ARP_DEFAULT_MAXREC, // SenderMaxRec TODO
  800. pPktData
  801. );
  802. RM_ASSERT_NOLOCKS(pSR);
  803. TR_WARN(("Attempting to send ARP Resp PKT. UID=0x%I64x FIFO=0x%04lx:0x%08lx OP=%lu SIP=0x%04lx TIP=0x%04lx.\n",
  804. pPktInfo->SenderHwAddr.UniqueID,
  805. pPktInfo->SenderHwAddr.Off_High,
  806. pPktInfo->SenderHwAddr.Off_Low,
  807. pPktInfo->OpCode,
  808. pPktInfo->SenderIpAddress,
  809. pPktInfo->TargetIpAddress
  810. ));
  811. ARP_FASTREADLOCK_IF_SEND_LOCK(pIF);
  812. // Actually send the packet (this will silently fail and free the pkt
  813. // if we're not in a position to send the pkt.)
  814. //
  815. arpSendControlPkt(
  816. pIF, // LOCKIN NOLOCKOUT (IF send lk)
  817. pNdisPacket,
  818. pIF->pBroadcastDest,
  819. pSR
  820. );
  821. }
  822. }
  823. RM_ASSERT_NOLOCKS(pSR);
  824. }
  825. VOID
  826. arpProcessArpResponse(
  827. PARP1394_INTERFACE pIF, // NOLOCKIN NOLOCKOUT
  828. PIP1394_ARP_PKT_INFO pPktInfo,
  829. PRM_STACK_RECORD pSR
  830. )
  831. {
  832. ARP_DEST_PARAMS DestParams;
  833. RM_ASSERT_NOLOCKS(pSR);
  834. ARP_ZEROSTRUCT(&DestParams);
  835. DestParams.HwAddr.AddressType = NIC1394AddressType_FIFO;
  836. DestParams.HwAddr.FifoAddress = pPktInfo->SenderHwAddr; // Struct copy
  837. arpUpdateArpCache(
  838. pIF,
  839. pPktInfo->SenderIpAddress, // Remote IP Address
  840. NULL, // Senders Mac Address (Bridge only)
  841. &DestParams, // Remote Destination HW Address
  842. FALSE, // Don't update unless we already have an entry for it.
  843. pSR
  844. );
  845. }
  846. VOID
  847. arpUpdateArpCache(
  848. PARP1394_INTERFACE pIF, // NOLOCKIN NOLOCKOUT
  849. IP_ADDRESS RemoteIpAddress,
  850. ENetAddr *pRemoteEthAddress,
  851. PARP_DEST_PARAMS pDestParams,
  852. MYBOOL fCreateIfRequired,
  853. PRM_STACK_RECORD pSR
  854. )
  855. /*++
  856. Update cache and also abort any resolution task that may be going on.
  857. --*/
  858. {
  859. REMOTE_DEST_KEY RemoteDestKey;
  860. PARP1394_ADAPTER pAdapter = (PARP1394_ADAPTER)RM_PARENT_OBJECT(pIF);
  861. ENTER("arpUpdateArpCache", 0x3a16a415)
  862. LOCKOBJ(pIF, pSR);
  863. do
  864. {
  865. ARPCB_REMOTE_IP *pRemoteIp = NULL;
  866. INT fCreated = FALSE;
  867. UINT RemoteIpCreateFlags = 0;
  868. NDIS_STATUS Status;
  869. DBGMARK(0xd3b27d1f);
  870. if (fCreateIfRequired)
  871. {
  872. RemoteIpCreateFlags |= RM_CREATE;
  873. }
  874. // Create the Key from the passed in parameters
  875. //
  876. if (ARP_BRIDGE_ENABLED(pAdapter) == TRUE)
  877. {
  878. ASSERT (pRemoteEthAddress != NULL);
  879. RemoteDestKey.ENetAddress = *pRemoteEthAddress;
  880. TR_INFO(("Arp1394 - Bridge update cache Mac Address %x %x %x %x %x %x\n",
  881. RemoteDestKey.ENetAddress.addr[0],
  882. RemoteDestKey.ENetAddress.addr[1],
  883. RemoteDestKey.ENetAddress.addr[2],
  884. RemoteDestKey.ENetAddress.addr[3],
  885. RemoteDestKey.ENetAddress.addr[4],
  886. RemoteDestKey.ENetAddress.addr[5]));
  887. }
  888. else
  889. {
  890. REMOTE_DEST_KEY_INIT(&RemoteDestKey);
  891. RemoteDestKey.IpAddress = RemoteIpAddress;
  892. TR_INFO( ("Arp1394 - Non-Bridge update cache Mac Address %x %x %x %x %x %x\n",
  893. RemoteDestKey.ENetAddress.addr[0],
  894. RemoteDestKey.ENetAddress.addr[1],
  895. RemoteDestKey.ENetAddress.addr[2],
  896. RemoteDestKey.ENetAddress.addr[3],
  897. RemoteDestKey.ENetAddress.addr[4],
  898. RemoteDestKey.ENetAddress.addr[5]));
  899. }
  900. // Lookup/Create Remote IP Address
  901. //
  902. Status = RmLookupObjectInGroup(
  903. &pIF->RemoteIpGroup,
  904. RemoteIpCreateFlags,
  905. (PVOID) (&RemoteDestKey),
  906. (PVOID) (&RemoteDestKey), // pCreateParams
  907. (RM_OBJECT_HEADER**) &pRemoteIp,
  908. &fCreated, // pfCreated
  909. pSR
  910. );
  911. if (FAIL(Status))
  912. {
  913. OBJLOG1(
  914. pIF,
  915. "Couldn't add localIp entry with addr 0x%lx\n",
  916. RemoteIpAddress
  917. );
  918. break;
  919. }
  920. //
  921. // Update the RemoteIp Last time checked here. This will refresh the
  922. // Arp Entry for this Remote Ip struct
  923. //
  924. pRemoteIp->sendinfo.TimeLastChecked = 0;
  925. UNLOCKOBJ(pIF, pSR);
  926. arpUpdateRemoteIpDest(
  927. pIF,
  928. pRemoteIp,
  929. pDestParams,
  930. pSR
  931. );
  932. // If there is a resolution task going on for pRemoteIp we abort it.
  933. //
  934. arpTryAbortResolutionTask(pRemoteIp, pSR);
  935. // Finally, remove the tmprefs added in the lookups.
  936. //
  937. RmTmpDereferenceObject(&pRemoteIp->Hdr, pSR);
  938. return; // EARLY RETURN
  939. } while (FALSE);
  940. UNLOCKOBJ(pIF, pSR);
  941. EXIT()
  942. }
  943. VOID
  944. arpTryAbortResolutionTask(
  945. PARPCB_REMOTE_IP pRemoteIp, // NOLOCKIN NOLOCKOUT
  946. PRM_STACK_RECORD pSR
  947. )
  948. {
  949. ENTER("arpTryAbortResolutionTask", 0xf34f16f2)
  950. PTASK_RESOLVE_IP_ADDRESS pResolutionTask;
  951. UINT TaskResumed;
  952. RM_ASSERT_NOLOCKS(pSR);
  953. LOCKOBJ(pRemoteIp, pSR);
  954. pResolutionTask = (PTASK_RESOLVE_IP_ADDRESS) pRemoteIp->pResolutionTask;
  955. if (pResolutionTask != NULL)
  956. {
  957. RmTmpReferenceObject(&pResolutionTask->TskHdr.Hdr, pSR);
  958. }
  959. UNLOCKOBJ(pRemoteIp, pSR);
  960. DBGMARK(0x5b93ad3e);
  961. if (pResolutionTask != NULL)
  962. {
  963. RmResumeDelayedTaskNow(
  964. &pResolutionTask->TskHdr,
  965. &pResolutionTask->Timer,
  966. &TaskResumed,
  967. pSR
  968. );
  969. RmTmpDereferenceObject(&pResolutionTask->TskHdr.Hdr, pSR);
  970. }
  971. EXIT()
  972. }