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.

1524 lines
41 KiB

  1. /*++
  2. Copyright (c) 1996 Microsoft Corporation
  3. Module Name:
  4. ioctl.c
  5. Abstract:
  6. Handler routines for Internal IOCTLs, including IOCTL_ARP1394_REQUEST.
  7. Revision History:
  8. Who When What
  9. -------- -------- ----------------------------------------------
  10. josephj 11-20-97 Created
  11. Notes:
  12. --*/
  13. #include <precomp.h>
  14. // #include "ioctl.h"
  15. //
  16. // File-specific debugging defaults.
  17. //
  18. #define TM_CURRENT TM_NT
  19. NTSTATUS
  20. arpDoClientCommand(
  21. PARP1394_IOCTL_COMMAND pCmd,
  22. UINT BufLen
  23. );
  24. NTSTATUS
  25. arpDoEthernetCommand(
  26. PARP1394_IOCTL_COMMAND pCmd,
  27. UINT BufLen
  28. );
  29. NTSTATUS
  30. arpIoctlGetArpCache(
  31. PARP1394_INTERFACE pIF,
  32. PARP1394_IOCTL_GET_ARPCACHE pGetCacheCmd,
  33. PRM_STACK_RECORD pSR
  34. );
  35. NTSTATUS
  36. arpIoctlAddArpEntry(
  37. PARP1394_INTERFACE pIF,
  38. PARP1394_IOCTL_ADD_ARP_ENTRY pAddArpEntryCmd,
  39. PRM_STACK_RECORD pSR
  40. );
  41. NTSTATUS
  42. arpIoctlDelArpEntry(
  43. PARP1394_INTERFACE pIF,
  44. PARP1394_IOCTL_DEL_ARP_ENTRY pDelArpEntryCmd,
  45. PRM_STACK_RECORD pSR
  46. );
  47. NTSTATUS
  48. arpIoctlPurgeArpCache(
  49. PARP1394_INTERFACE pIF,
  50. PARP1394_IOCTL_PURGE_ARPCACHE pPurgeCmd,
  51. PRM_STACK_RECORD pSR
  52. );
  53. NTSTATUS
  54. arpIoctlGetPacketStats(
  55. PARP1394_INTERFACE pIF,
  56. PARP1394_IOCTL_GET_PACKET_STATS pStatsCmd,
  57. PRM_STACK_RECORD pSR
  58. );
  59. NTSTATUS
  60. arpIoctlGetTaskStats(
  61. PARP1394_INTERFACE pIF,
  62. PARP1394_IOCTL_GET_TASK_STATS pStatsCmd,
  63. PRM_STACK_RECORD pSR
  64. );
  65. NTSTATUS
  66. arpIoctlGetArpStats(
  67. PARP1394_INTERFACE pIF,
  68. PARP1394_IOCTL_GET_ARPCACHE_STATS pStatsCmd,
  69. PRM_STACK_RECORD pSR
  70. );
  71. NTSTATUS
  72. arpIoctlGetCallStats(
  73. PARP1394_INTERFACE pIF,
  74. PARP1394_IOCTL_GET_CALL_STATS pStatsCmd,
  75. PRM_STACK_RECORD pSR
  76. );
  77. NTSTATUS
  78. arpIoctlResetStats(
  79. PARP1394_INTERFACE pIF,
  80. PARP1394_IOCTL_RESET_STATS pResetStatsCmd,
  81. PRM_STACK_RECORD pSR
  82. );
  83. NTSTATUS
  84. arpIoctlReinitIf(
  85. PARP1394_INTERFACE pIF,
  86. PARP1394_IOCTL_REINIT_INTERFACE pReinitCmd,
  87. PRM_STACK_RECORD pSR
  88. );
  89. PARP1394_INTERFACE
  90. arpGetIfByIp(
  91. IN OUT IP_ADDRESS *pLocalIpAddress, // OPTIONAL
  92. PRM_STACK_RECORD pSR
  93. );
  94. UINT
  95. arpGetStatsDuration(
  96. PARP1394_INTERFACE pIF
  97. );
  98. NTSTATUS
  99. arpIoctlSendPacket(
  100. PARP1394_INTERFACE pIF,
  101. PARP1394_IOCTL_SEND_PACKET pSendPacket,
  102. PRM_STACK_RECORD pSR
  103. );
  104. NTSTATUS
  105. arpIoctlRecvPacket(
  106. PARP1394_INTERFACE pIF,
  107. PARP1394_IOCTL_RECV_PACKET pRecvPacket,
  108. PRM_STACK_RECORD pSR
  109. );
  110. NTSTATUS
  111. arpIoctlGetNicInfo(
  112. PARP1394_INTERFACE pIF,
  113. PARP1394_IOCTL_NICINFO pIoctlNicInfo,
  114. PRM_STACK_RECORD pSR
  115. );
  116. NTSTATUS
  117. arpIoctlGetEuidNodeMacInfo(
  118. PARP1394_INTERFACE pIF,
  119. PARP1394_IOCTL_EUID_NODE_MAC_INFO pEuidInfo,
  120. PRM_STACK_RECORD pSR
  121. );
  122. NTSTATUS
  123. ArpHandleIoctlRequest(
  124. IN PIRP pIrp,
  125. IN PIO_STACK_LOCATION pIrpSp
  126. )
  127. /*++
  128. Routine Description:
  129. Private IOCTL interface to the ARP1394 administration utility.
  130. --*/
  131. {
  132. NTSTATUS NtStatus = STATUS_UNSUCCESSFUL;
  133. PUCHAR pBuf;
  134. UINT BufLen;
  135. ULONG Code;
  136. ENTER("Ioctl", 0x4e96d522)
  137. pIrp->IoStatus.Information = 0;
  138. pBuf = pIrp->AssociatedIrp.SystemBuffer;
  139. BufLen = pIrpSp->Parameters.DeviceIoControl.InputBufferLength;
  140. Code = pIrpSp->Parameters.DeviceIoControl.IoControlCode;
  141. TR_WARN(("Code = 0x%p\n", Code));
  142. if (Code == ARP_IOCTL_CLIENT_OPERATION && pBuf != NULL)
  143. {
  144. PARP1394_IOCTL_COMMAND pCmd;
  145. pCmd = (PARP1394_IOCTL_COMMAND) pBuf;
  146. if ( (pCmd->Hdr.Op >= ARP1394_IOCTL_OP_ETHERNET_FIRST)
  147. && (pCmd->Hdr.Op <= ARP1394_IOCTL_OP_ETHERNET_LAST))
  148. {
  149. // This is an ethernet-emulation related ioctl request (from
  150. // NIC1394.SYS). We handle these differently.
  151. //
  152. NtStatus = arpDoEthernetCommand(pCmd, BufLen);
  153. }
  154. else
  155. {
  156. NtStatus = arpDoClientCommand(pCmd, BufLen);
  157. }
  158. //
  159. // All commands return stuff in pCmd itself...
  160. //
  161. if (NtStatus == STATUS_SUCCESS)
  162. {
  163. pIrp->IoStatus.Information = BufLen;
  164. }
  165. }
  166. else
  167. {
  168. TR_WARN(("Unrecognized code.\n"));
  169. }
  170. EXIT()
  171. return NtStatus;
  172. }
  173. NTSTATUS
  174. arpDoClientCommand(
  175. PARP1394_IOCTL_COMMAND pCmd,
  176. UINT BufLen
  177. )
  178. {
  179. ENTER("arpDoClientCommand", 0xd7985f1b)
  180. NTSTATUS NtStatus = STATUS_UNSUCCESSFUL;
  181. PARP1394_INTERFACE pIF;
  182. RM_DECLARE_STACK_RECORD(sr)
  183. do
  184. {
  185. IP_ADDRESS IpAddress;
  186. pIF = NULL;
  187. if (pCmd == NULL)
  188. {
  189. TR_WARN(("Invalid buffer %p\n", pCmd));
  190. break;
  191. }
  192. if (BufLen<sizeof(pCmd->Hdr))
  193. {
  194. TR_WARN(("Buffer too small (%lu)\n", BufLen));
  195. break;
  196. }
  197. if (pCmd->Hdr.Version != ARP1394_IOCTL_VERSION)
  198. {
  199. TR_WARN(("Incorrect version 0x%08lx\n", pCmd->Hdr.Version));
  200. break;
  201. }
  202. IpAddress = (IP_ADDRESS) pCmd->Hdr.IfIpAddress;
  203. // IpAddress could be all-zeros, in which case we'll get the first IF,
  204. // and IpAddress will be set to one of the local IP addresses of this IF.
  205. // NOTE: pIF is tmpref'd.
  206. //
  207. pIF = arpGetIfByIp(&IpAddress, &sr);
  208. if (pIF == NULL)
  209. {
  210. TR_WARN(("Couldn't find IF with IP 0x%0x8lx\n", IpAddress));
  211. break;
  212. }
  213. pCmd->Hdr.IfIpAddress = IpAddress;
  214. switch(pCmd->Hdr.Op)
  215. {
  216. case ARP1394_IOCTL_OP_GET_ARPCACHE:
  217. {
  218. PARP1394_IOCTL_GET_ARPCACHE pGetArpCache = &pCmd->GetArpCache;
  219. if (BufLen >= sizeof(*pGetArpCache))
  220. {
  221. //
  222. // Check if there is enough space for all the arp entries.
  223. //
  224. ULONG EntrySpace;
  225. EntrySpace = BufLen - FIELD_OFFSET(
  226. ARP1394_IOCTL_GET_ARPCACHE,
  227. Entries
  228. );
  229. if ((EntrySpace/sizeof(pGetArpCache->Entries[0])) >
  230. pGetArpCache->NumEntriesAvailable)
  231. {
  232. //
  233. // Yes, there is enough space.
  234. //
  235. NtStatus = arpIoctlGetArpCache(pIF, pGetArpCache, &sr);
  236. }
  237. }
  238. }
  239. break;
  240. case ARP1394_IOCTL_OP_ADD_STATIC_ENTRY:
  241. {
  242. PARP1394_IOCTL_ADD_ARP_ENTRY pAddCmd = &pCmd->AddArpEntry;
  243. if (BufLen >= sizeof(*pAddCmd))
  244. {
  245. NtStatus = arpIoctlAddArpEntry(pIF, pAddCmd, &sr);
  246. }
  247. }
  248. break;
  249. case ARP1394_IOCTL_OP_DEL_STATIC_ENTRY:
  250. {
  251. PARP1394_IOCTL_DEL_ARP_ENTRY pDelCmd = &pCmd->DelArpEntry;
  252. if (BufLen >= sizeof(*pDelCmd))
  253. {
  254. NtStatus = arpIoctlDelArpEntry(pIF, pDelCmd, &sr);
  255. }
  256. }
  257. break;
  258. case ARP1394_IOCTL_OP_PURGE_ARPCACHE:
  259. {
  260. PARP1394_IOCTL_PURGE_ARPCACHE pPurge = &pCmd->PurgeArpCache;
  261. if (BufLen >= sizeof(*pPurge))
  262. {
  263. NtStatus = arpIoctlPurgeArpCache(pIF, pPurge, &sr);
  264. }
  265. }
  266. break;
  267. case ARP1394_IOCTL_OP_GET_PACKET_STATS:
  268. {
  269. PARP1394_IOCTL_GET_PACKET_STATS pStats = &pCmd->GetPktStats;
  270. if (BufLen >= sizeof(*pStats))
  271. {
  272. NtStatus = arpIoctlGetPacketStats(pIF, pStats, &sr);
  273. }
  274. }
  275. break;
  276. case ARP1394_IOCTL_OP_GET_TASK_STATS:
  277. {
  278. PARP1394_IOCTL_GET_TASK_STATS pStats = &pCmd->GetTaskStats;
  279. if (BufLen >= sizeof(*pStats))
  280. {
  281. NtStatus = arpIoctlGetTaskStats(pIF, pStats, &sr);
  282. }
  283. }
  284. break;
  285. case ARP1394_IOCTL_OP_GET_ARPCACHE_STATS:
  286. {
  287. PARP1394_IOCTL_GET_ARPCACHE_STATS pStats = &pCmd->GetArpStats;
  288. if (BufLen >= sizeof(*pStats))
  289. {
  290. NtStatus = arpIoctlGetArpStats(pIF, pStats, &sr);
  291. }
  292. }
  293. break;
  294. case ARP1394_IOCTL_OP_GET_CALL_STATS:
  295. {
  296. PARP1394_IOCTL_GET_CALL_STATS pStats = &pCmd->GetCallStats;
  297. if (BufLen >= sizeof(*pStats))
  298. {
  299. NtStatus = arpIoctlGetCallStats(pIF, pStats, &sr);
  300. }
  301. }
  302. break;
  303. case ARP1394_IOCTL_OP_RESET_STATS:
  304. {
  305. PARP1394_IOCTL_RESET_STATS pResetStats = &pCmd->ResetStats;
  306. if (BufLen >= sizeof(*pResetStats))
  307. {
  308. NtStatus = arpIoctlResetStats(pIF, pResetStats, &sr);
  309. }
  310. }
  311. break;
  312. case ARP1394_IOCTL_OP_REINIT_INTERFACE:
  313. {
  314. PARP1394_IOCTL_REINIT_INTERFACE pReinitIf = &pCmd->ReinitInterface;
  315. if (BufLen >= sizeof(*pReinitIf))
  316. {
  317. NtStatus = arpIoctlReinitIf(pIF, pReinitIf, &sr);
  318. }
  319. }
  320. break;
  321. case ARP1394_IOCTL_OP_SEND_PACKET:
  322. {
  323. ARP1394_IOCTL_SEND_PACKET *pSendPacket = &pCmd->SendPacket;
  324. if (BufLen >= sizeof(*pSendPacket))
  325. {
  326. NtStatus = arpIoctlSendPacket(pIF, pSendPacket, &sr);
  327. }
  328. }
  329. break;
  330. case ARP1394_IOCTL_OP_RECV_PACKET:
  331. {
  332. ARP1394_IOCTL_RECV_PACKET *pRecvPacket = &pCmd->RecvPacket;
  333. if (BufLen >= sizeof(*pRecvPacket))
  334. {
  335. NtStatus = arpIoctlRecvPacket(pIF, pRecvPacket, &sr);
  336. }
  337. }
  338. break;
  339. case ARP1394_IOCTL_OP_GET_NICINFO:
  340. {
  341. ARP1394_IOCTL_NICINFO *pIoctlNicInfo = &pCmd->IoctlNicInfo;
  342. if (BufLen >= sizeof(*pIoctlNicInfo))
  343. {
  344. NtStatus = arpIoctlGetNicInfo(pIF, pIoctlNicInfo, &sr);
  345. }
  346. }
  347. break;
  348. case ARP1394_IOCTL_OP_GET_EUID_NODE_MAC_TABLE:
  349. {
  350. PARP1394_IOCTL_EUID_NODE_MAC_INFO pIoctlEuidInfo = &pCmd->EuidNodeMacInfo;
  351. if (BufLen >= sizeof(*pIoctlEuidInfo))
  352. {
  353. NtStatus = arpIoctlGetEuidNodeMacInfo(pIF, pIoctlEuidInfo, &sr);
  354. }
  355. }
  356. break;
  357. default:
  358. TR_WARN(("Unknown op %lu\n", pCmd->Hdr.Op));
  359. break;
  360. }
  361. } while (FALSE);
  362. if (NtStatus != STATUS_SUCCESS)
  363. {
  364. TR_WARN(("Command unsuccessful. NtStatus = 0x%lx\n", NtStatus));
  365. }
  366. if (pIF != NULL)
  367. {
  368. RmTmpDereferenceObject(&pIF->Hdr, &sr);
  369. }
  370. RM_ASSERT_CLEAR(&sr);
  371. EXIT()
  372. return NtStatus;
  373. }
  374. NTSTATUS
  375. arpDoEthernetCommand(
  376. PARP1394_IOCTL_COMMAND pCmd,
  377. UINT BufLen
  378. )
  379. {
  380. ENTER("arpDoEthernetCommand", 0xa723f233)
  381. PARP1394_IOCTL_ETHERNET_NOTIFICATION pNotif;
  382. PARP1394_ADAPTER pAdapter = NULL;
  383. RM_DECLARE_STACK_RECORD(sr)
  384. pNotif = (PARP1394_IOCTL_ETHERNET_NOTIFICATION) pCmd;
  385. do
  386. {
  387. NDIS_STATUS NdisStatus = NDIS_STATUS_FAILURE;
  388. NDIS_STRING DeviceName;
  389. if (BufLen<sizeof(*pNotif))
  390. {
  391. TR_WARN(("Buffer too small (%lu)\n", BufLen));
  392. break;
  393. }
  394. if (pNotif->Hdr.Version != ARP1394_IOCTL_VERSION)
  395. {
  396. TR_WARN(("Incorrect version 0x%08lx\n", pCmd->Hdr.Version));
  397. break;
  398. }
  399. NdisInitUnicodeString(&DeviceName, pNotif->AdapterName);
  400. if (pNotif->Hdr.Op == ARP1394_IOCTL_OP_ETHERNET_START_EMULATION)
  401. {
  402. //
  403. // ArpNdBindAdapter will try to create the adapter in "Bridge
  404. // mode" if it passed in a NULL bind context.
  405. // It will of course fail if the adapter exists.
  406. //
  407. ArpNdBindAdapter(
  408. &NdisStatus,
  409. NULL, // BindContext
  410. &DeviceName, // pDeviceName
  411. NULL, // SystemSpecific1
  412. NULL // SystemSpecific2
  413. );
  414. break;
  415. }
  416. //
  417. // The remaining operations concern an existing adapter which has been
  418. // created in "bridge" mode. Let's look up this adapter based on it's
  419. // name.
  420. //
  421. NdisStatus = RmLookupObjectInGroup(
  422. &ArpGlobals.adapters.Group,
  423. 0, // Flags
  424. (PVOID) &DeviceName, // pKey
  425. NULL, // pvCreateParams
  426. &(PRM_OBJECT_HEADER) pAdapter, // pObj
  427. NULL, // pfCreated
  428. &sr
  429. );
  430. if (FAIL(NdisStatus))
  431. {
  432. TR_WARN(("Couldn't find adapter object\n"));
  433. pAdapter = NULL;
  434. break;
  435. }
  436. if (!ARP_BRIDGE_ENABLED(pAdapter))
  437. {
  438. TR_WARN((
  439. "Ignoring Ethernet Emulation Ioctl Op 0x%x"
  440. " because adapter 0x%p is not in bridge mode.\n",
  441. pNotif->Hdr.Op,
  442. pAdapter));
  443. break;
  444. }
  445. //
  446. // OK -- we've found the adapter and the adapter is in bridged mode.
  447. // Let's look at the specific command.
  448. //
  449. switch(pNotif->Hdr.Op)
  450. {
  451. case ARP1394_IOCTL_OP_ETHERNET_STOP_EMULATION:
  452. {
  453. // Calling ArpNdUnbindAdapter with NULL UnbindContext prevents
  454. // it from trying to call NdisCompleteUnbindAdapter.
  455. //
  456. ArpNdUnbindAdapter(
  457. &NdisStatus,
  458. (NDIS_HANDLE) pAdapter,
  459. NULL // UnbindContext
  460. );
  461. }
  462. break;
  463. case ARP1394_IOCTL_OP_ETHERNET_ADD_MULTICAST_ADDRESS:
  464. {
  465. // TODO: unimplemented.
  466. }
  467. break;
  468. case ARP1394_IOCTL_OP_ETHERNET_DEL_MULTICAST_ADDRESS:
  469. {
  470. // TODO: unimplemented.
  471. }
  472. break;
  473. case ARP1394_IOCTL_OP_ETHERNET_ENABLE_PROMISCUOUS_MODE:
  474. {
  475. // TODO: unimplemented.
  476. }
  477. break;
  478. case ARP1394_IOCTL_OP_ETHERNET_DISABLE_PROMISCUOUS_MODE:
  479. {
  480. // TODO: unimplemented.
  481. }
  482. break;
  483. default:
  484. TR_WARN(("Unknown op %lu\n", pCmd->Hdr.Op));
  485. break;
  486. }
  487. } while (FALSE);
  488. if (pAdapter != NULL)
  489. {
  490. RmTmpDereferenceObject(&pAdapter->Hdr, &sr);
  491. }
  492. RM_ASSERT_CLEAR(&sr);
  493. EXIT()
  494. return STATUS_SUCCESS;
  495. }
  496. NTSTATUS
  497. arpIoctlGetArpCache(
  498. PARP1394_INTERFACE pIF,
  499. PARP1394_IOCTL_GET_ARPCACHE pGetCacheCmd,
  500. PRM_STACK_RECORD pSR
  501. )
  502. {
  503. ENTER("GetArpCache", 0xa64453c7)
  504. NTSTATUS NtStatus;
  505. TR_WARN(("GET ARP CACHE\n"));
  506. pGetCacheCmd->NumEntriesUsed = 0;
  507. NtStatus = STATUS_UNSUCCESSFUL;
  508. do
  509. {
  510. PARP1394_ADAPTER pAdapter;
  511. PARP1394_ARP_ENTRY pEntry;
  512. ARPCB_REMOTE_IP * pRemoteIp;
  513. NDIS_STATUS Status;
  514. UINT EntriesAvailable;
  515. UINT EntriesUsed;
  516. UINT CurIndex;
  517. UINT Index;
  518. LOCKOBJ(pIF, pSR);
  519. pAdapter = (ARP1394_ADAPTER*) RM_PARENT_OBJECT(pIF);
  520. pGetCacheCmd->NumEntriesInArpCache = pIF->RemoteIpGroup.HashTable.NumItems;
  521. pGetCacheCmd->LocalHwAddress.UniqueID= pAdapter->info.LocalUniqueID;
  522. pGetCacheCmd->LocalHwAddress.Off_Low = pIF->recvinfo.offset.Off_Low;
  523. pGetCacheCmd->LocalHwAddress.Off_High= pIF->recvinfo.offset.Off_High;
  524. //
  525. // Pick up pGetCacheCmd->NumEntriesAvailable arp entries starting
  526. // from the (pGetCacheCmd->Index)'th one.
  527. //
  528. pRemoteIp = NULL;
  529. EntriesAvailable = pGetCacheCmd->NumEntriesAvailable;
  530. EntriesUsed = 0;
  531. Index = pGetCacheCmd->Index;
  532. pEntry = pGetCacheCmd->Entries;
  533. CurIndex = 0;
  534. // Get the 1st entry...
  535. //
  536. Status = RmGetNextObjectInGroup(
  537. &pIF->RemoteIpGroup,
  538. NULL,
  539. &(PRM_OBJECT_HEADER)pRemoteIp,
  540. pSR
  541. );
  542. if (FAIL(Status))
  543. {
  544. // Presumably there are no entries.
  545. pRemoteIp = NULL;
  546. }
  547. while (pRemoteIp != NULL)
  548. {
  549. ARPCB_REMOTE_IP * pNextRemoteIp = NULL;
  550. if (EntriesUsed >= EntriesAvailable)
  551. {
  552. //
  553. // out of space; Update the context, and set special return value.
  554. //
  555. RmTmpDereferenceObject(&pRemoteIp->Hdr, pSR);
  556. pRemoteIp = NULL;
  557. break;
  558. }
  559. // If this entry is within the range asked for, we copy the IP and
  560. // HW address over onto pEntry...
  561. //
  562. if (CurIndex >= Index)
  563. {
  564. ARP_ZEROSTRUCT(pEntry);
  565. pEntry->IpAddress = pRemoteIp->Key.IpAddress;
  566. if (CHECK_REMOTEIP_RESOLVE_STATE(pRemoteIp, ARPREMOTEIP_RESOLVED))
  567. {
  568. ARPCB_DEST *pDest = pRemoteIp->pDest;
  569. TR_INFO(("ReadNext: found Remote IP Entry 0x%x, Addr %d.%d.%d.%d\n",
  570. pRemoteIp,
  571. ((PUCHAR)(&(pRemoteIp->IpAddress)))[0],
  572. ((PUCHAR)(&(pRemoteIp->IpAddress)))[1],
  573. ((PUCHAR)(&(pRemoteIp->IpAddress)))[2],
  574. ((PUCHAR)(&(pRemoteIp->IpAddress)))[3]
  575. ));
  576. // We assert that
  577. // IF lock is the same as pRemoteIp's and pDest's lock,
  578. // and that lock is locked.
  579. // We implicitly assert that pDest is non-NULl as well.
  580. //
  581. ASSERTEX(pRemoteIp->Hdr.pLock == pDest->Hdr.pLock, pRemoteIp);
  582. RM_DBG_ASSERT_LOCKED(&pRemoteIp->Hdr, pSR);
  583. pEntry->HwAddress.UniqueID = pDest->Params.HwAddr.FifoAddress.UniqueID;
  584. pEntry->HwAddress.Off_Low = pDest->Params.HwAddr.FifoAddress.Off_Low;
  585. pEntry->HwAddress.Off_High = pDest->Params.HwAddr.FifoAddress.Off_High;
  586. if (CHECK_REMOTEIP_SDTYPE(pRemoteIp, ARPREMOTEIP_STATIC))
  587. {
  588. // TODO
  589. }
  590. else
  591. {
  592. // TODO
  593. }
  594. }
  595. else
  596. {
  597. // TODO
  598. }
  599. pEntry++;
  600. EntriesUsed++;
  601. }
  602. // Lookup next entry's IP address and save it in our context.
  603. //
  604. Status = RmGetNextObjectInGroup(
  605. &pIF->RemoteIpGroup,
  606. &pRemoteIp->Hdr,
  607. &(PRM_OBJECT_HEADER)pNextRemoteIp,
  608. pSR
  609. );
  610. if (FAIL(Status))
  611. {
  612. //
  613. // we're presumably done.
  614. //
  615. pNextRemoteIp = NULL;
  616. }
  617. // TmpDeref pRemoteIp and move on to the next one.
  618. //
  619. RmTmpDereferenceObject(&pRemoteIp->Hdr, pSR);
  620. pRemoteIp = pNextRemoteIp;
  621. }
  622. ASSERT(pRemoteIp == NULL);
  623. UNLOCKOBJ(pIF, pSR);
  624. ASSERT(EntriesUsed <= pGetCacheCmd->NumEntriesAvailable);
  625. pGetCacheCmd->NumEntriesUsed = EntriesUsed;
  626. NtStatus = STATUS_SUCCESS;
  627. } while (FALSE);
  628. EXIT()
  629. return NtStatus;
  630. }
  631. NTSTATUS
  632. arpIoctlAddArpEntry(
  633. PARP1394_INTERFACE pIF,
  634. PARP1394_IOCTL_ADD_ARP_ENTRY pAddArpEntryCmd,
  635. PRM_STACK_RECORD pSR
  636. )
  637. {
  638. ENTER("AddArpEntry", 0xcda56c6f)
  639. NTSTATUS NtStatus;
  640. TR_WARN(("ADD ARP ENTRY\n"));
  641. NtStatus = STATUS_UNSUCCESSFUL;
  642. do
  643. {
  644. NDIS_STATUS Status;
  645. NIC1394_FIFO_ADDRESS FifoAddress;
  646. LOCKOBJ(pIF, pSR);
  647. FifoAddress.UniqueID = pAddArpEntryCmd->HwAddress.UniqueID;
  648. FifoAddress.Off_Low = pAddArpEntryCmd->HwAddress.Off_Low;
  649. FifoAddress.Off_High = pAddArpEntryCmd->HwAddress.Off_High;
  650. //
  651. // TODO -- we hardcode the Off_Low and Off_High values for now...
  652. //
  653. FifoAddress.Off_Low = 0x0;
  654. FifoAddress.Off_High = 0x100;
  655. // Actually add the entry...
  656. //
  657. Status = arpAddOneStaticArpEntry(
  658. pIF,
  659. pAddArpEntryCmd->IpAddress,
  660. &FifoAddress,
  661. pSR
  662. );
  663. UNLOCKOBJ(pIF, pSR);
  664. if (!FAIL(Status))
  665. {
  666. NtStatus = STATUS_SUCCESS;
  667. }
  668. } while (FALSE);
  669. EXIT()
  670. return NtStatus;
  671. }
  672. NTSTATUS
  673. arpIoctlDelArpEntry(
  674. PARP1394_INTERFACE pIF,
  675. PARP1394_IOCTL_DEL_ARP_ENTRY pDelArpEntryCmd,
  676. PRM_STACK_RECORD pSR
  677. )
  678. {
  679. ENTER("DelArpEntry", 0x3427306a)
  680. NTSTATUS NtStatus;
  681. TR_WARN(("DEL ARP ENTRY\n"));
  682. NtStatus = STATUS_UNSUCCESSFUL;
  683. NtStatus = arpDelArpEntry(pIF,pDelArpEntryCmd->IpAddress,pSR);
  684. EXIT()
  685. return NtStatus;
  686. }
  687. NTSTATUS
  688. arpIoctlPurgeArpCache(
  689. PARP1394_INTERFACE pIF,
  690. PARP1394_IOCTL_PURGE_ARPCACHE pPurgeCmd,
  691. PRM_STACK_RECORD pSR
  692. )
  693. {
  694. ENTER("PurgeArpCache", 0x2bebb833)
  695. TR_WARN(("PURGE ARP CACHE\n"));
  696. return 0;
  697. }
  698. NTSTATUS
  699. arpIoctlGetPacketStats(
  700. PARP1394_INTERFACE pIF,
  701. PARP1394_IOCTL_GET_PACKET_STATS pStatsCmd,
  702. PRM_STACK_RECORD pSR
  703. )
  704. {
  705. ENTER("GetPacketStats", 0xe7c75fdb)
  706. NTSTATUS NtStatus;
  707. TR_WARN(("GET PACKET STATS\n"));
  708. NtStatus = STATUS_UNSUCCESSFUL;
  709. do
  710. {
  711. NDIS_STATUS Status;
  712. pStatsCmd->StatsDuration = arpGetStatsDuration(pIF);
  713. pStatsCmd->TotSends = pIF->stats.sendpkts.TotSends;
  714. pStatsCmd->FastSends = pIF->stats.sendpkts.FastSends;
  715. pStatsCmd->MediumSends = pIF->stats.sendpkts.MediumSends;
  716. pStatsCmd->SlowSends = pIF->stats.sendpkts.SlowSends;
  717. pStatsCmd->BackFills = pIF->stats.sendpkts.BackFills;
  718. // TODO: report pIF->sendinfo.HeaderPool.stats.TotAllocFails
  719. pStatsCmd->HeaderBufUses =
  720. pIF->sendinfo.HeaderPool.stats.TotBufAllocs
  721. + pIF->sendinfo.HeaderPool.stats.TotCacheAllocs;
  722. pStatsCmd->HeaderBufCacheHits =
  723. pIF->sendinfo.HeaderPool.stats.TotCacheAllocs;
  724. pStatsCmd->TotRecvs = pIF->stats.recvpkts.TotRecvs;
  725. pStatsCmd->NoCopyRecvs = pIF->stats.recvpkts.NoCopyRecvs;
  726. pStatsCmd->CopyRecvs = pIF->stats.recvpkts.CopyRecvs;
  727. pStatsCmd->ResourceRecvs = pIF->stats.recvpkts.ResourceRecvs;
  728. pStatsCmd->SendFifoCounts = pIF->stats.sendpkts.SendFifoCounts;
  729. pStatsCmd->RecvFifoCounts = pIF->stats.recvpkts.RecvFifoCounts;
  730. pStatsCmd->SendChannelCounts = pIF->stats.sendpkts.SendChannelCounts;
  731. pStatsCmd->RecvChannelCounts = pIF->stats.recvpkts.RecvChannelCounts;
  732. NtStatus = STATUS_SUCCESS;
  733. } while (FALSE);
  734. EXIT()
  735. return NtStatus;
  736. }
  737. NTSTATUS
  738. arpIoctlGetTaskStats(
  739. PARP1394_INTERFACE pIF,
  740. PARP1394_IOCTL_GET_TASK_STATS pStatsCmd,
  741. PRM_STACK_RECORD pSR
  742. )
  743. {
  744. ENTER("GetTaskStats", 0x4abc46b5)
  745. TR_WARN(("GET TASK STATS\n"));
  746. return 0;
  747. }
  748. NTSTATUS
  749. arpIoctlGetArpStats(
  750. PARP1394_INTERFACE pIF,
  751. PARP1394_IOCTL_GET_ARPCACHE_STATS pStatsCmd,
  752. PRM_STACK_RECORD pSR
  753. )
  754. {
  755. ENTER("GetArpStats", 0x5482de10)
  756. TR_WARN(("GET ARP STATS\n"));
  757. pStatsCmd->StatsDuration = arpGetStatsDuration(pIF);
  758. pStatsCmd->TotalQueries = pIF->stats.arpcache.TotalQueries;
  759. pStatsCmd->SuccessfulQueries = pIF->stats.arpcache.SuccessfulQueries;
  760. pStatsCmd->FailedQueries = pIF->stats.arpcache.FailedQueries;
  761. pStatsCmd->TotalResponses = pIF->stats.arpcache.TotalResponses;
  762. pStatsCmd->TotalLookups = pIF->stats.arpcache.TotalLookups;
  763. pStatsCmd->TraverseRatio = RM_HASH_TABLE_TRAVERSE_RATIO(
  764. &(pIF->RemoteIpGroup.HashTable)
  765. );
  766. EXIT()
  767. return STATUS_SUCCESS;
  768. }
  769. NTSTATUS
  770. arpIoctlGetCallStats(
  771. PARP1394_INTERFACE pIF,
  772. PARP1394_IOCTL_GET_CALL_STATS pStatsCmd,
  773. PRM_STACK_RECORD pSR
  774. )
  775. {
  776. ENTER("GetCallStats", 0xf81ed4cf)
  777. TR_WARN(("GET CALL STATS\n"));
  778. //
  779. // FIFO-related call stats.
  780. //
  781. pStatsCmd->TotalSendFifoMakeCalls =
  782. pIF->stats.calls.TotalSendFifoMakeCalls;
  783. pStatsCmd->SuccessfulSendFifoMakeCalls =
  784. pIF->stats.calls.SuccessfulSendFifoMakeCalls;
  785. pStatsCmd->FailedSendFifoMakeCalls =
  786. pIF->stats.calls.FailedSendFifoMakeCalls;
  787. pStatsCmd->IncomingClosesOnSendFifos =
  788. pIF->stats.calls.IncomingClosesOnSendFifos;
  789. //
  790. // Channel-related call stats.
  791. //
  792. pStatsCmd->TotalChannelMakeCalls =
  793. pIF->stats.calls.TotalChannelMakeCalls;
  794. pStatsCmd->SuccessfulChannelMakeCalls =
  795. pIF->stats.calls.SuccessfulChannelMakeCalls;
  796. pStatsCmd->FailedChannelMakeCalls =
  797. pIF->stats.calls.FailedChannelMakeCalls;
  798. pStatsCmd->IncomingClosesOnChannels =
  799. pIF->stats.calls.IncomingClosesOnChannels;
  800. return STATUS_SUCCESS;
  801. }
  802. NTSTATUS
  803. arpIoctlResetStats(
  804. PARP1394_INTERFACE pIF,
  805. PARP1394_IOCTL_RESET_STATS pResetStatsCmd,
  806. PRM_STACK_RECORD pSR
  807. )
  808. {
  809. NTSTATUS NtStatus;
  810. ENTER("ResetStats", 0xfa50cfc9)
  811. TR_WARN(("RESET STATS\n"));
  812. NtStatus = STATUS_UNSUCCESSFUL;
  813. do
  814. {
  815. NDIS_STATUS Status;
  816. NIC1394_FIFO_ADDRESS FifoAddress;
  817. LOCKOBJ(pIF, pSR);
  818. arpResetIfStats(pIF, pSR);
  819. UNLOCKOBJ(pIF, pSR);
  820. NtStatus = STATUS_SUCCESS;
  821. } while (FALSE);
  822. EXIT()
  823. return NtStatus;
  824. }
  825. NTSTATUS
  826. arpIoctlReinitIf(
  827. PARP1394_INTERFACE pIF,
  828. PARP1394_IOCTL_REINIT_INTERFACE pReinitIfCmd,
  829. PRM_STACK_RECORD pSR
  830. )
  831. {
  832. ENTER("ReinitIf", 0xed00187a)
  833. NTSTATUS NtStatus;
  834. TR_WARN(("REINIT IF\n"));
  835. NtStatus = STATUS_UNSUCCESSFUL;
  836. do
  837. {
  838. NDIS_STATUS Status;
  839. NIC1394_FIFO_ADDRESS FifoAddress;
  840. Status = arpTryReconfigureIf(pIF, NULL, pSR);
  841. if (PEND(Status) || !FAIL(Status))
  842. {
  843. NtStatus = STATUS_SUCCESS;
  844. }
  845. } while (FALSE);
  846. EXIT()
  847. return NtStatus;
  848. }
  849. PARP1394_INTERFACE
  850. arpGetIfByIp(
  851. IN OUT IP_ADDRESS *pLocalIpAddress, // OPTIONAL
  852. PRM_STACK_RECORD pSR
  853. )
  854. /*++
  855. Routine Description:
  856. Find and return the 1st (and usually only) interface which has
  857. *pLocalIpAddress as a local IP address.
  858. If pLocalIpAddress is NULL, or *pLocalIpAddress is 0, return the
  859. first interface.
  860. Tmpref the interface before returning it.
  861. --*/
  862. {
  863. ENTER("arpGetIfByIp", 0xe9667c54)
  864. PARP1394_ADAPTER pAdapter = NULL;
  865. PARP1394_INTERFACE pIF = NULL;
  866. PARP1394_INTERFACE pFirstIF = NULL;
  867. NDIS_STATUS Status;
  868. IP_ADDRESS LocalIpAddress = 0;
  869. if (pLocalIpAddress != NULL)
  870. {
  871. LocalIpAddress = *pLocalIpAddress;
  872. }
  873. //
  874. // We iterate through all adapters, and for each adapter we look
  875. // for the specified ip address in the IF's LocalIp group.
  876. //
  877. // Get the 1st adapter...
  878. //
  879. Status = RmGetNextObjectInGroup(
  880. &ArpGlobals.adapters.Group,
  881. NULL,
  882. &(PRM_OBJECT_HEADER)pAdapter,
  883. pSR
  884. );
  885. if (FAIL(Status))
  886. {
  887. pAdapter = NULL;
  888. }
  889. while (pAdapter != NULL)
  890. {
  891. ARP1394_ADAPTER * pNextAdapter = NULL;
  892. // Check if this adapter's interface has the local ip address.
  893. //
  894. LOCKOBJ(pAdapter, pSR);
  895. ASSERT(pIF==NULL);
  896. pIF = pAdapter->pIF;
  897. if (pIF != NULL)
  898. {
  899. RmTmpReferenceObject(&pIF->Hdr, pSR);
  900. if (pFirstIF == NULL)
  901. {
  902. pFirstIF = pIF;
  903. RmTmpReferenceObject(&pFirstIF->Hdr, pSR);
  904. }
  905. }
  906. UNLOCKOBJ(pAdapter, pSR);
  907. if (pIF != NULL)
  908. {
  909. PARPCB_LOCAL_IP pLocalIp;
  910. LOCKOBJ(pIF, pSR);
  911. if (LocalIpAddress != 0)
  912. {
  913. Status = RmLookupObjectInGroup(
  914. &pIF->LocalIpGroup,
  915. 0, // Flags
  916. (PVOID) ULongToPtr (LocalIpAddress), // pKey
  917. NULL, // pvCreateParams
  918. &(PRM_OBJECT_HEADER)pLocalIp,
  919. NULL, // pfCreated
  920. pSR
  921. );
  922. }
  923. else
  924. {
  925. PARPCB_LOCAL_IP pPrevLocalIp = NULL;
  926. do
  927. {
  928. Status = RmGetNextObjectInGroup(
  929. &pIF->LocalIpGroup,
  930. &(pPrevLocalIp)->Hdr,
  931. &(PRM_OBJECT_HEADER)pLocalIp,
  932. pSR
  933. );
  934. if (pPrevLocalIp != NULL)
  935. {
  936. RmTmpDereferenceObject(&pPrevLocalIp->Hdr, pSR);
  937. }
  938. pPrevLocalIp = pLocalIp;
  939. //
  940. // we need to keep looking until we find a UNICAST
  941. // local ip address!
  942. //
  943. } while (!FAIL(Status) && pLocalIp->IpAddressType!=LLIP_ADDR_LOCAL);
  944. }
  945. UNLOCKOBJ(pIF, pSR);
  946. if (FAIL(Status))
  947. {
  948. // This IF is not the one, sorry...
  949. //
  950. RmTmpDereferenceObject(&pIF->Hdr, pSR);
  951. pIF = NULL;
  952. }
  953. else
  954. {
  955. // Found a local IP address (either matching or first one).
  956. // Let's get out of here...
  957. //
  958. if (pLocalIpAddress != NULL)
  959. {
  960. *pLocalIpAddress = pLocalIp->IpAddress;
  961. }
  962. RmTmpDereferenceObject(&pLocalIp->Hdr, pSR);
  963. RmTmpDereferenceObject(&pAdapter->Hdr, pSR);
  964. pLocalIp = NULL;
  965. pAdapter = NULL;
  966. //
  967. // Note: we keep the reference on pIF, which we return.
  968. //
  969. break; // break out of the enclosing while(adapters-left) loop.
  970. }
  971. }
  972. // Lookup next adapter.
  973. //
  974. Status = RmGetNextObjectInGroup(
  975. &ArpGlobals.adapters.Group,
  976. &pAdapter->Hdr,
  977. &(PRM_OBJECT_HEADER)pNextAdapter,
  978. pSR
  979. );
  980. if (FAIL(Status))
  981. {
  982. //
  983. // we're presumably done.
  984. //
  985. pNextAdapter = NULL;
  986. }
  987. // TmpDeref pAdapter and move on to the next one.
  988. //
  989. RmTmpDereferenceObject(&pAdapter->Hdr, pSR);
  990. pAdapter = pNextAdapter;
  991. }
  992. //
  993. // If LocalipAddress ==0 AND
  994. // if we couldn't find any IF with any local IP address
  995. // (this would be because we haven't started an IF as yet)
  996. // we return the first IF we find.
  997. //
  998. if (LocalIpAddress == 0 && pIF == NULL)
  999. {
  1000. pIF = pFirstIF;
  1001. pFirstIF = NULL;
  1002. }
  1003. if (pFirstIF != NULL)
  1004. {
  1005. RmTmpDereferenceObject(&pFirstIF->Hdr, pSR);
  1006. }
  1007. return pIF;
  1008. }
  1009. UINT
  1010. arpGetStatsDuration(
  1011. PARP1394_INTERFACE pIF
  1012. )
  1013. /*++
  1014. Return duration in seconds since start of statistics gathering.
  1015. --*/
  1016. {
  1017. LARGE_INTEGER liCurrent;
  1018. // Get the current time (in 100-nanosecond units).
  1019. //
  1020. NdisGetCurrentSystemTime(&liCurrent);
  1021. // Compute the difference since the start of stats collection.
  1022. //
  1023. liCurrent.QuadPart -= pIF->stats.StatsResetTime.QuadPart;
  1024. // Convert to seconds.
  1025. //
  1026. liCurrent.QuadPart /= 10000000;
  1027. // return low part.
  1028. //
  1029. return liCurrent.LowPart;
  1030. }
  1031. NTSTATUS
  1032. arpIoctlSendPacket(
  1033. PARP1394_INTERFACE pIF,
  1034. PARP1394_IOCTL_SEND_PACKET pSendPacket,
  1035. PRM_STACK_RECORD pSR
  1036. )
  1037. /*++
  1038. Send the pSendPacket->PacketSize bytes of data in pSendPacket->Data as
  1039. a single packet on the broadcast channel. The encap header is expected
  1040. to be already in the packet.
  1041. --*/
  1042. {
  1043. ENTER("IoctlSendPacket", 0x59746279)
  1044. NTSTATUS NtStatus;
  1045. RM_ASSERT_NOLOCKS(pSR);
  1046. TR_WARN(("SEND PACKET\n"));
  1047. NtStatus = STATUS_UNSUCCESSFUL;
  1048. do
  1049. {
  1050. NDIS_STATUS Status;
  1051. PNDIS_PACKET pNdisPacket;
  1052. PVOID pPktData;
  1053. UINT Size = pSendPacket->PacketSize;
  1054. //
  1055. // Validate contents of pSendPacket.
  1056. //
  1057. if (Size > sizeof(pSendPacket->Data))
  1058. {
  1059. TR_WARN(("PacketSize value %lu is too large.\n", Size));
  1060. break;
  1061. }
  1062. //
  1063. // Allocate a control packet and copy over the contents.
  1064. //
  1065. Status = arpAllocateControlPacket(
  1066. pIF,
  1067. Size,
  1068. ARP1394_PACKET_FLAGS_IOCTL,
  1069. &pNdisPacket,
  1070. &pPktData,
  1071. pSR
  1072. );
  1073. if (FAIL(Status))
  1074. {
  1075. TR_WARN(("Couldn't allocate send packet.\n"));
  1076. break;
  1077. }
  1078. NdisMoveMemory(pPktData, pSendPacket->Data, Size);
  1079. ARP_FASTREADLOCK_IF_SEND_LOCK(pIF);
  1080. // Actually send the packet (this will silently fail and free the pkt
  1081. // if we're not in a position to send the pkt.)
  1082. //
  1083. arpSendControlPkt(
  1084. pIF, // LOCKIN NOLOCKOUT (IF send lk)
  1085. pNdisPacket,
  1086. pIF->pBroadcastDest,
  1087. pSR
  1088. );
  1089. NtStatus = STATUS_SUCCESS;
  1090. } while (FALSE);
  1091. RM_ASSERT_NOLOCKS(pSR);
  1092. EXIT()
  1093. return NtStatus;
  1094. }
  1095. NTSTATUS
  1096. arpIoctlRecvPacket(
  1097. PARP1394_INTERFACE pIF,
  1098. PARP1394_IOCTL_RECV_PACKET pRecvPacket,
  1099. PRM_STACK_RECORD pSR
  1100. )
  1101. {
  1102. ENTER("IoctlRecvPacket", 0x59746279)
  1103. NTSTATUS NtStatus;
  1104. RM_ASSERT_NOLOCKS(pSR);
  1105. TR_WARN(("RECV PACKET\n"));
  1106. NtStatus = STATUS_UNSUCCESSFUL;
  1107. do
  1108. {
  1109. NDIS_STATUS Status;
  1110. PNDIS_PACKET pNdisPacket;
  1111. PVOID pPktData;
  1112. UINT Size = pRecvPacket->PacketSize;
  1113. //
  1114. // Validate contents of pRecvPacket.
  1115. //
  1116. if (Size > sizeof(pRecvPacket->Data))
  1117. {
  1118. TR_WARN(("PacketSize value %lu is too large.\n", Size));
  1119. break;
  1120. }
  1121. //
  1122. // Allocate a control packet and copy over the contents.
  1123. //
  1124. Status = arpAllocateControlPacket(
  1125. pIF,
  1126. Size,
  1127. ARP1394_PACKET_FLAGS_IOCTL,
  1128. &pNdisPacket,
  1129. &pPktData,
  1130. pSR
  1131. );
  1132. if (FAIL(Status))
  1133. {
  1134. TR_WARN(("Couldn't allocate recv packet.\n"));
  1135. break;
  1136. }
  1137. NdisMoveMemory(pPktData, pRecvPacket->Data, Size);
  1138. //
  1139. // Set the packet flags to STATUS_RESOURCES, so that our receive-
  1140. // indicate handler will return synchronously.
  1141. //
  1142. NDIS_SET_PACKET_STATUS (pNdisPacket, NDIS_STATUS_RESOURCES);
  1143. //
  1144. // Call our internal common receive packet handler.
  1145. //
  1146. arpProcessReceivedPacket(
  1147. pIF,
  1148. pNdisPacket,
  1149. TRUE // IsChannel
  1150. );
  1151. //
  1152. // Now we free the packet.
  1153. //
  1154. arpFreeControlPacket(
  1155. pIF,
  1156. pNdisPacket,
  1157. pSR
  1158. );
  1159. NtStatus = STATUS_SUCCESS;
  1160. } while (FALSE);
  1161. RM_ASSERT_NOLOCKS(pSR);
  1162. EXIT()
  1163. return NtStatus;
  1164. }
  1165. NTSTATUS
  1166. arpIoctlGetNicInfo(
  1167. PARP1394_INTERFACE pIF,
  1168. PARP1394_IOCTL_NICINFO pIoctlNicInfo,
  1169. PRM_STACK_RECORD pSR
  1170. )
  1171. {
  1172. ENTER("IoctlGetNicInfo", 0x637c44e0)
  1173. NTSTATUS NtStatus = STATUS_UNSUCCESSFUL;
  1174. ARP_NDIS_REQUEST ArpNdisRequest;
  1175. PARP1394_ADAPTER pAdapter;
  1176. pAdapter = (ARP1394_ADAPTER*) RM_PARENT_OBJECT(pIF);
  1177. do
  1178. {
  1179. NDIS_STATUS Status;
  1180. if (pIoctlNicInfo->Info.Hdr.Version != NIC1394_NICINFO_VERSION)
  1181. {
  1182. TR_WARN(("NicInfo version mismatch. Want 0x%lx, got 0x%lx.\n",
  1183. NIC1394_NICINFO_VERSION, pIoctlNicInfo->Info.Hdr.Version));
  1184. break;
  1185. }
  1186. //
  1187. // Copy over all the fields.
  1188. //
  1189. Status = arpPrepareAndSendNdisRequest(
  1190. pAdapter,
  1191. &ArpNdisRequest,
  1192. NULL, // pTask (NULL==BLOCK)
  1193. 0, // unused
  1194. OID_1394_NICINFO,
  1195. &pIoctlNicInfo->Info,
  1196. sizeof(pIoctlNicInfo->Info),
  1197. NdisRequestQueryInformation,
  1198. pSR
  1199. );
  1200. if (FAIL(Status))
  1201. {
  1202. TR_WARN(("NdisRequest failed with error 0x%08lx.\n", Status));
  1203. break;
  1204. }
  1205. if (pIoctlNicInfo->Info.Hdr.Version != NIC1394_NICINFO_VERSION)
  1206. {
  1207. TR_WARN(("Unexpected NIC NicInfo version 0x%lx returned.\n",
  1208. pIoctlNicInfo->Info.Hdr.Version));
  1209. break;
  1210. }
  1211. NtStatus = NDIS_STATUS_SUCCESS;
  1212. } while (FALSE);
  1213. return NtStatus;
  1214. }
  1215. NTSTATUS
  1216. arpIoctlGetEuidNodeMacInfo(
  1217. PARP1394_INTERFACE pIF,
  1218. PARP1394_IOCTL_EUID_NODE_MAC_INFO pEuidInfo,
  1219. PRM_STACK_RECORD pSR
  1220. )
  1221. {
  1222. ENTER("IoctlGetNicInfo", 0x34db9cf4)
  1223. NTSTATUS NtStatus = STATUS_UNSUCCESSFUL;
  1224. ARP_NDIS_REQUEST ArpNdisRequest;
  1225. PARP1394_ADAPTER pAdapter;
  1226. pAdapter = (ARP1394_ADAPTER*) RM_PARENT_OBJECT(pIF);
  1227. do
  1228. {
  1229. NDIS_STATUS Status;
  1230. //
  1231. // Copy over all the fields.
  1232. //
  1233. Status = arpPrepareAndSendNdisRequest(
  1234. pAdapter,
  1235. &ArpNdisRequest,
  1236. NULL, // pTask (NULL==BLOCK)
  1237. 0, // unused
  1238. OID_1394_QUERY_EUID_NODE_MAP,
  1239. &pEuidInfo->Map,
  1240. sizeof(pEuidInfo->Map),
  1241. NdisRequestQueryInformation,
  1242. pSR
  1243. );
  1244. if (FAIL(Status))
  1245. {
  1246. TR_WARN(("NdisRequest failed with error 0x%08lx.\n", Status));
  1247. break;
  1248. }
  1249. NtStatus = NDIS_STATUS_SUCCESS;
  1250. } while (FALSE);
  1251. return NtStatus;
  1252. }