internal static NetworkInterface[] GetNetworkInterfaces()
{
Contract.Ensures(Contract.Result <NetworkInterface[]>() != null);
AddressFamily family = AddressFamily.Unspecified;
uint bufferSize = 0;
SafeLocalAllocHandle buffer = null;
// TODO: #2485: This will probably require changes in the PAL for HostInformation.
Interop.IpHlpApi.FIXED_INFO fixedInfo = HostInformationPal.GetFixedInfo();
List <SystemNetworkInterface> interfaceList = new List <SystemNetworkInterface>();
Interop.IpHlpApi.GetAdaptersAddressesFlags flags =
Interop.IpHlpApi.GetAdaptersAddressesFlags.IncludeGateways
| Interop.IpHlpApi.GetAdaptersAddressesFlags.IncludeWins;
// Figure out the right buffer size for the adapter information.
uint result = Interop.IpHlpApi.GetAdaptersAddresses(
family, (uint)flags, IntPtr.Zero, SafeLocalAllocHandle.Zero, ref bufferSize);
while (result == Interop.IpHlpApi.ERROR_BUFFER_OVERFLOW)
{
// Allocate the buffer and get the adapter info.
using (buffer = SafeLocalAllocHandle.LocalAlloc((int)bufferSize))
{
result = Interop.IpHlpApi.GetAdaptersAddresses(
family, (uint)flags, IntPtr.Zero, buffer, ref bufferSize);
// If succeeded, we're going to add each new interface.
if (result == Interop.IpHlpApi.ERROR_SUCCESS)
{
// Linked list of interfaces.
IntPtr ptr = buffer.DangerousGetHandle();
while (ptr != IntPtr.Zero)
{
// Traverse the list, marshal in the native structures, and create new NetworkInterfaces.
Interop.IpHlpApi.IpAdapterAddresses adapterAddresses = Marshal.PtrToStructure <Interop.IpHlpApi.IpAdapterAddresses>(ptr);
interfaceList.Add(new SystemNetworkInterface(fixedInfo, adapterAddresses));
ptr = adapterAddresses.next;
}
}
}
}
// If we don't have any interfaces detected, return empty.
if (result == Interop.IpHlpApi.ERROR_NO_DATA || result == Interop.IpHlpApi.ERROR_INVALID_PARAMETER)
{
return(new SystemNetworkInterface[0]);
}
// Otherwise we throw on an error.
if (result != Interop.IpHlpApi.ERROR_SUCCESS)
{
throw new NetworkInformationException((int)result);
}
return(interfaceList.ToArray());
}