Leaked source code of windows server 2003
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.

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