From 092c5ad023bb2c28985272b1d90c705fd58d4e50 Mon Sep 17 00:00:00 2001 From: =?utf8?q?J=C3=A9r=C3=B4me=20Gardou?= Date: Tue, 4 Nov 2014 10:38:43 +0000 Subject: [PATCH] [IPHLPAPI] - Retrieve unicast addresses and prefixes in GetAdaptersAddresses. svn path=/trunk/; revision=65242 --- reactos/dll/win32/iphlpapi/address.c | 129 +++++++++++++++++++++++++-- 1 file changed, 121 insertions(+), 8 deletions(-) diff --git a/reactos/dll/win32/iphlpapi/address.c b/reactos/dll/win32/iphlpapi/address.c index dc58f83836a..ad8c561c0db 100644 --- a/reactos/dll/win32/iphlpapi/address.c +++ b/reactos/dll/win32/iphlpapi/address.c @@ -89,7 +89,6 @@ GetInterfacesList( return Status; } -#if 0 static NTSTATUS GetSnmpInfo( @@ -128,7 +127,46 @@ GetSnmpInfo( return Status; } -#endif + +static +NTSTATUS +GetAddrEntries( + _In_ HANDLE TcpFile, + _In_ TDIEntityID InterfaceID, + _Out_ IPAddrEntry* Entries, + _In_ ULONG NumEntries) +{ + TCP_REQUEST_QUERY_INFORMATION_EX TcpQueryInfo; + IO_STATUS_BLOCK StatusBlock; + NTSTATUS Status; + + ZeroMemory(&TcpQueryInfo, sizeof(TcpQueryInfo)); + TcpQueryInfo.ID.toi_class = INFO_CLASS_PROTOCOL; + TcpQueryInfo.ID.toi_type = INFO_TYPE_PROVIDER; + TcpQueryInfo.ID.toi_id = IP_MIB_ADDRTABLE_ENTRY_ID; + TcpQueryInfo.ID.toi_entity = InterfaceID; + + Status = NtDeviceIoControlFile( + TcpFile, + NULL, + NULL, + NULL, + &StatusBlock, + IOCTL_TCP_QUERY_INFORMATION_EX, + &TcpQueryInfo, + sizeof(TcpQueryInfo), + Entries, + NumEntries * sizeof(Entries[0])); + if (Status == STATUS_PENDING) + { + /* So we have to wait a bit */ + Status = NtWaitForSingleObject(TcpFile, FALSE, NULL); + if (NT_SUCCESS(Status)) + Status = StatusBlock.Status; + } + + return Status; +} /* * Fills the IFEntry buffer from tcpip.sys. @@ -439,14 +477,17 @@ GetAdaptersAddresses( return ERROR_NO_DATA; } -/* Disabled for now until someone knows how to differentiate unicast/multicast whatver adresses */ -#if 0 - /* See what we will fill our buffer with */ + /* See if we have anything to add */ + // FIXME: Anycast and multicast + if ((Flags & (GAA_FLAG_SKIP_UNICAST | GAA_FLAG_INCLUDE_PREFIX)) == GAA_FLAG_SKIP_UNICAST) + goto Success; + + /* Now fill in the addresses */ for (i = 0; i < InterfacesCount; i++) { /* Look for network layers */ - if ((InterfacesList[i].tei_entity == CL_TL_ENTITY) - || (InterfacesList[i].tei_entity == CO_TL_ENTITY)) + if ((InterfacesList[i].tei_entity == CL_NL_ENTITY) + || (InterfacesList[i].tei_entity == CO_NL_ENTITY)) { IPSNMPInfo SnmpInfo; PIP_ADAPTER_ADDRESSES CurrentAA = NULL; @@ -458,6 +499,9 @@ GetAdaptersAddresses( if (!NT_SUCCESS(Status)) goto Error; + if (SnmpInfo.ipsi_numaddr == 0) + continue; + /* Allocate the address entry array and get them */ AddrEntries = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, @@ -493,12 +537,81 @@ GetAdaptersAddresses( continue; } } + + ERR("address is 0x%08x, mask is 0x%08x\n", AddrEntries[j].iae_addr, AddrEntries[j].iae_mask); + + //FIXME: For now reactos only supports unicast addresses + if (!(Flags & GAA_FLAG_SKIP_UNICAST)) + { + ULONG Size = sizeof(IP_ADAPTER_UNICAST_ADDRESS) + sizeof(SOCKADDR); + + if (Ptr && (RemainingSize >= Size)) + { + PIP_ADAPTER_UNICAST_ADDRESS UnicastAddress = (PIP_ADAPTER_UNICAST_ADDRESS)Ptr; + + /* Fill in the structure */ + UnicastAddress->Length = sizeof(IP_ADAPTER_UNICAST_ADDRESS); + UnicastAddress->Next = CurrentAA->FirstUnicastAddress; + + // FIXME: Put meaningful value here + UnicastAddress->Flags = 0; + UnicastAddress->PrefixOrigin = IpPrefixOriginOther; + UnicastAddress->SuffixOrigin = IpSuffixOriginOther; + UnicastAddress->DadState = IpDadStatePreferred; + UnicastAddress->ValidLifetime = 0xFFFFFFFF; + UnicastAddress->PreferredLifetime = 0xFFFFFFFF; + + /* Set the address */ + //FIXME: ipv4 only (again...) + UnicastAddress->Address.lpSockaddr = (LPSOCKADDR)(UnicastAddress + 1); + UnicastAddress->Address.iSockaddrLength = sizeof(AddrEntries[j].iae_addr); + UnicastAddress->Address.lpSockaddr->sa_family = AF_INET; + memcpy(UnicastAddress->Address.lpSockaddr->sa_data, &AddrEntries[j].iae_addr, sizeof(AddrEntries[j].iae_addr)); + + CurrentAA->FirstUnicastAddress = UnicastAddress; + Ptr += Size; + RemainingSize -= Size; + } + + TotalSize += Size; + } + + if (Flags & GAA_FLAG_INCLUDE_PREFIX) + { + ULONG Size = sizeof(IP_ADAPTER_PREFIX) + sizeof(SOCKADDR); + + if (Ptr && (RemainingSize >= Size)) + { + PIP_ADAPTER_PREFIX Prefix = (PIP_ADAPTER_PREFIX)Ptr; + + /* Fill in the structure */ + Prefix->Length = sizeof(IP_ADAPTER_PREFIX); + Prefix->Next = CurrentAA->FirstPrefix; + + /* Set the address */ + //FIXME: ipv4 only (again...) + Prefix->Address.lpSockaddr = (LPSOCKADDR)(Prefix + 1); + Prefix->Address.iSockaddrLength = sizeof(AddrEntries[j].iae_mask); + Prefix->Address.lpSockaddr->sa_family = AF_INET; + memcpy(Prefix->Address.lpSockaddr->sa_data, &AddrEntries[j].iae_mask, sizeof(AddrEntries[j].iae_mask)); + + /* Compute the prefix size */ + _BitScanReverse(&Prefix->PrefixLength, AddrEntries[j].iae_mask); + + CurrentAA->FirstPrefix = Prefix; + Ptr += Size; + RemainingSize -= Size; + } + + TotalSize += Size; + } } + HeapFree(GetProcessHeap(), 0, AddrEntries); } } -#endif +Success: /* We're done */ HeapFree(GetProcessHeap(), 0, InterfacesList); NtClose(TcpFile); -- 2.17.1