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.

407 lines
8.1 KiB

  1. /*++
  2. Copyright (c) 1996 Microsoft Corporation
  3. Module Name:
  4. ioctl.c
  5. Abstract:
  6. Handler routines for Internal IOCTLs, including IOCTL_ATMARP_REQUEST
  7. to resolve an IP address to an ATM address.
  8. Revision History:
  9. Who When What
  10. -------- -------- ----------------------------------------------
  11. arvindm 09-16-96 Created
  12. Notes:
  13. --*/
  14. #include <precomp.h>
  15. #include "ioctl.h"
  16. #define _FILENUMBER 'TCOI'
  17. #if !BINARY_COMPATIBLE
  18. #ifdef CUBDD
  19. NTSTATUS
  20. AtmArpInternalDeviceControl(
  21. IN PDEVICE_OBJECT pDeviceObject,
  22. IN PIRP pIrp
  23. )
  24. /*++
  25. Routine Description:
  26. This entry point is called by the System when somebody sends an
  27. "Internal" IOCTL to us.
  28. Arguments:
  29. pDeviceObject - Pointer to device object we created for ourselves.
  30. pIrp - Pointer to IRP to be processed.
  31. Return Value:
  32. None
  33. --*/
  34. {
  35. NTSTATUS Status; // Return value
  36. PIO_STACK_LOCATION pIrpStack;
  37. ULONG OutputBufferLength; // Space for output values
  38. ULONG IoControlCode; // Operation to be performed
  39. PATMARP_INTERFACE pInterface; // IF to which this op is directed
  40. //
  41. // Initialize
  42. //
  43. Status = STATUS_UNSUCCESSFUL;
  44. pIrp->IoStatus.Status = STATUS_UNSUCCESSFUL;
  45. pIrp->IoStatus.Information = 0;
  46. //
  47. // Get all information in the IRP
  48. //
  49. pIrpStack = IoGetCurrentIrpStackLocation(pIrp);
  50. OutputBufferLength = pIrpStack->Parameters.DeviceIoControl.OutputBufferLength;
  51. IoControlCode = pIrpStack->MinorFunction;
  52. IoMarkIrpPending(pIrp);
  53. pInterface = (PATMARP_INTERFACE)pIrpStack->FileObject->FsContext;
  54. AADEBUGP(AAD_VERY_LOUD,
  55. ("Internal Ctl: IF 0x%x, Code 0x%x, pIrp 0x%x, UserBuf 0x%x\n",
  56. pInterface, IoControlCode, pIrp, pIrp->UserBuffer));
  57. switch (IoControlCode)
  58. {
  59. case IOCTL_ATMARP_REQUEST:
  60. Status = AtmArpIoctlArpRequest(
  61. pInterface,
  62. pIrp
  63. );
  64. break;
  65. default:
  66. Status = STATUS_UNSUCCESSFUL;
  67. break;
  68. }
  69. if (Status != NDIS_STATUS_PENDING)
  70. {
  71. pIrpStack->Control &= ~SL_PENDING_RETURNED;
  72. pIrp->IoStatus.Status = Status;
  73. IoCompleteRequest(pIrp, IO_NO_INCREMENT);
  74. }
  75. return (Status);
  76. }
  77. NTSTATUS
  78. AtmArpIoctlArpRequest(
  79. IN PATMARP_INTERFACE pInterface OPTIONAL,
  80. IN PIRP pIrp
  81. )
  82. /*++
  83. Routine Description:
  84. Handle an ARP request from CUB-DD to resolve an IP address to an
  85. ATM address on the given Interface. If we already have a mapping in
  86. the ARP table, we return the corresponding ATM address. Otherwise,
  87. we initiate Address Resolution, unless the process is already going
  88. on.
  89. A special case is a NULL value of pInterface, meaning search for
  90. the IP address on all available Interfaces. This special case is not
  91. supported.
  92. Arguments:
  93. pInterface - Pointer to ATMARP Interface, if known.
  94. pIrp - Pointer to IRP carrying the request.
  95. Return Value:
  96. STATUS_SUCCESS if we found a match (we copy in the ATM address
  97. into the UserBuffer if so).
  98. STATUS_PENDING if we didn't find a match, but address resolution is
  99. in progress.
  100. STATUS_UNSUCCESSFUL if we didn't find a match, and couldn't start
  101. address resolution for the IP address.
  102. --*/
  103. {
  104. PIO_STACK_LOCATION pIrpStack;
  105. NTSTATUS Status;
  106. PATMARP_IP_ENTRY pIpEntry;
  107. PATMARP_ATM_ENTRY pAtmEntry;
  108. PATMARP_REQUEST pRequest;
  109. IP_ADDRESS IPAddress;
  110. BOOLEAN IsBroadcast; // Is the requested address broadcast/multicast?
  111. ATMARP_REQUEST Request;
  112. pIrpStack = IoGetCurrentIrpStackLocation(pIrp);
  113. Status = STATUS_SUCCESS;
  114. do
  115. {
  116. if (pInterface == NULL_PATMARP_INTERFACE)
  117. {
  118. AADEBUGP(AAD_WARNING, ("IoctlArpRequest: NULL IF: failing request\n"));
  119. Status = STATUS_UNSUCCESSFUL;
  120. break;
  121. }
  122. if (pIrpStack->Parameters.Read.Length < sizeof(ATMARP_REQUEST))
  123. {
  124. AADEBUGP(AAD_WARNING, ("IoctlArpRequest: Length %d too small\n",
  125. pIrpStack->Parameters.Read.Length));
  126. Status = STATUS_INSUFFICIENT_RESOURCES;
  127. break;
  128. }
  129. AA_STRUCT_ASSERT(pInterface, aai);
  130. try
  131. {
  132. AA_COPY_MEM(&Request, pIrp->UserBuffer, sizeof(ATMARP_REQUEST));
  133. }
  134. except (EXCEPTION_EXECUTE_HANDLER)
  135. {
  136. Status = STATUS_UNSUCCESSFUL;
  137. }
  138. if (Status != STATUS_SUCCESS)
  139. {
  140. break;
  141. }
  142. pRequest = &Request;
  143. AA_ACQUIRE_IF_LOCK(pInterface);
  144. IsBroadcast = AtmArpIsBroadcastIPAddress(pRequest->IpAddress, pInterface);
  145. pIpEntry = AtmArpSearchForIPAddress(
  146. pInterface,
  147. (PIP_ADDRESS)&(pRequest->IpAddress),
  148. IE_REFTYPE_TMP,
  149. IsBroadcast,
  150. TRUE
  151. );
  152. AA_RELEASE_IF_LOCK(pInterface);
  153. if (pIpEntry != NULL_PATMARP_IP_ENTRY)
  154. {
  155. AA_ACQUIRE_IE_LOCK(pIpEntry);
  156. //
  157. // AtmArpSearchForIPAddress addreffs pIpEntry for us ...
  158. // Since this could be a new entry (ref count == 1), we
  159. // don't call AA_DEREF_IE -- instead we
  160. // simply decrement the ref count.
  161. //
  162. AA_ASSERT(pIpEntry->RefCount > 0);
  163. AA_DEREF_IE_NO_DELETE(pIpEntry, IE_REFTYPE_TMP);
  164. if (AA_IS_FLAG_SET(pIpEntry->Flags,
  165. AA_IP_ENTRY_STATE_MASK,
  166. AA_IP_ENTRY_RESOLVED))
  167. {
  168. AA_ASSERT(pIpEntry->RefCount > 0);
  169. AA_ASSERT(pIpEntry->pAtmEntry != NULL_PATMARP_ATM_ENTRY);
  170. pAtmEntry = pIpEntry->pAtmEntry;
  171. pRequest->HwAddressLength = pAtmEntry->ATMAddress.NumberOfDigits;
  172. AA_COPY_MEM(pRequest->HwAddress,
  173. pAtmEntry->ATMAddress.Address,
  174. ATM_ADDRESS_LENGTH);
  175. AA_RELEASE_IE_LOCK(pIpEntry);
  176. Status = STATUS_SUCCESS;
  177. //
  178. // Copy this back.
  179. //
  180. try
  181. {
  182. AA_COPY_MEM(&Request, pIrp->UserBuffer, sizeof(ATMARP_REQUEST));
  183. }
  184. except (EXCEPTION_EXECUTE_HANDLER)
  185. {
  186. Status = STATUS_UNSUCCESSFUL;
  187. }
  188. }
  189. else
  190. {
  191. //
  192. // Queue this IRP pending Address Resolution.
  193. //
  194. PushEntryList(&(pIpEntry->PendingIrpList),
  195. (PSINGLE_LIST_ENTRY)&(pIrp->Tail.Overlay.ListEntry));
  196. //
  197. // Start resolving this IP address, if not already resolving.
  198. //
  199. AtmArpResolveIpEntry(pIpEntry);
  200. //
  201. // IE Lock is released within the above.
  202. //
  203. Status = STATUS_PENDING;
  204. }
  205. }
  206. else
  207. {
  208. //
  209. // Couldn't find a matching IP Entry, and couldn't create
  210. // a new one either.
  211. //
  212. Status = STATUS_UNSUCCESSFUL;
  213. }
  214. break;
  215. }
  216. while (FALSE);
  217. if (Status == STATUS_SUCCESS)
  218. {
  219. pIrp->IoStatus.Information = 0;
  220. }
  221. return (Status);
  222. }
  223. VOID
  224. AtmArpCompleteArpIrpList(
  225. IN SINGLE_LIST_ENTRY ListHead,
  226. IN PATM_ADDRESS pAtmAddress OPTIONAL
  227. )
  228. /*++
  229. Routine Description:
  230. Complete a list of pended IRPs waiting for an IP address to be resolved
  231. to an ATM address. If resolution was successful, pAtmAddress is non-NULL,
  232. and points to the ATM address corresponding to the queried IP address.
  233. We copy in this ATM address into the IRP buffer, if successful. In any
  234. case, we complete all IRPs in the list.
  235. NOTE: we free the ATM Address structure here.
  236. Arguments:
  237. ListHead - Head of a list of pending IRPs.
  238. pAtmAddress - Pointer to ATM address if address resolution was successful.
  239. Return Value:
  240. None
  241. --*/
  242. {
  243. PSINGLE_LIST_ENTRY pEntry;
  244. PATMARP_REQUEST pRequest;
  245. PIRP pIrp;
  246. NTSTATUS Status;
  247. if (pAtmAddress != (PATM_ADDRESS)NULL)
  248. {
  249. Status = STATUS_SUCCESS;
  250. }
  251. else
  252. {
  253. Status = STATUS_UNSUCCESSFUL;
  254. }
  255. for (;;)
  256. {
  257. pEntry = PopEntryList(&ListHead);
  258. if (pEntry == (PSINGLE_LIST_ENTRY)NULL)
  259. {
  260. break;
  261. }
  262. pIrp = CONTAINING_RECORD(pEntry, IRP, Tail.Overlay.ListEntry);
  263. pRequest = (PATMARP_REQUEST)(pIrp->UserBuffer);
  264. try
  265. {
  266. if (pAtmAddress != (PATM_ADDRESS)NULL)
  267. {
  268. AA_COPY_MEM(pRequest->HwAddress,
  269. pAtmAddress->Address,
  270. ATM_ADDRESS_LENGTH);
  271. pRequest->HwAddressLength = pAtmAddress->NumberOfDigits;
  272. }
  273. }
  274. except (EXCEPTION_EXECUTE_HANDLER)
  275. {
  276. Status = STATUS_UNSUCCESSFUL;
  277. }
  278. AA_COMPLETE_IRP(pIrp, Status, 0);
  279. }
  280. if (pAtmAddress != (PATM_ADDRESS)NULL)
  281. {
  282. AA_FREE_MEM(pAtmAddress);
  283. }
  284. return;
  285. }
  286. #endif // CUBDD
  287. NTSTATUS
  288. AtmArpHandleIoctlRequest(
  289. IN PIRP pIrp,
  290. IN PIO_STACK_LOCATION pIrpSp
  291. )
  292. /*++
  293. Routine Description:
  294. Arguments:
  295. Return Value:
  296. --*/
  297. {
  298. NTSTATUS Status = STATUS_SUCCESS;
  299. PUCHAR pBuf;
  300. UINT BufLen;
  301. // PINTF pIntF = NULL;
  302. pIrp->IoStatus.Information = 0;
  303. pBuf = pIrp->AssociatedIrp.SystemBuffer;
  304. BufLen = pIrpSp->Parameters.DeviceIoControl.InputBufferLength;
  305. AADEBUGP(AAD_INFO,
  306. ("AtmArpHandleIoctlRequest: Code = 0x%lx\n",
  307. pIrpSp->Parameters.DeviceIoControl.IoControlCode));
  308. return Status;
  309. }
  310. #endif // !BINARY_COMPATIBLE