Thanks to visit codestin.com
Credit goes to github.com

Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -12,21 +12,34 @@ internal static partial class IpHlpApi
public const int MAX_DOMAIN_NAME_LEN = 128;
public const int MAX_SCOPE_ID_LEN = 256;

[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)]
public struct FIXED_INFO
[StructLayout(LayoutKind.Sequential)]
public unsafe struct FIXED_INFO
{
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = MAX_HOSTNAME_LEN + 4)]
public string hostName;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = MAX_DOMAIN_NAME_LEN + 4)]
public string domainName;
private fixed byte _hostName[MAX_HOSTNAME_LEN + 4];
public string HostName => CreateString(ref _hostName[0], MAX_HOSTNAME_LEN + 4);

private fixed byte _domainName[MAX_DOMAIN_NAME_LEN + 4];
public string DomainName => CreateString(ref _domainName[0], MAX_DOMAIN_NAME_LEN + 4);

public IntPtr currentDnsServer; // IpAddressList*
public IP_ADDR_STRING DnsServerList;
public uint nodeType;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = MAX_SCOPE_ID_LEN + 4)]
public string scopeId;
public bool enableRouting;
public bool enableProxy;
public bool enableDns;

private fixed byte _scopeId[MAX_SCOPE_ID_LEN + 4];
public string ScopeId => CreateString(ref _scopeId[0], MAX_SCOPE_ID_LEN + 4);

public uint enableRouting;
public uint enableProxy;
public uint enableDns;

private static string CreateString(ref byte firstByte, int maxLength)
{
fixed (byte* ptr = &firstByte)
{
int terminator = new ReadOnlySpan<byte>(ptr, maxLength).IndexOf((byte)0);
return Marshal.PtrToStringAnsi((IntPtr)ptr, (terminator >= 0) ? terminator : maxLength);
}
}
}
}
}
31 changes: 15 additions & 16 deletions src/libraries/Common/src/Interop/Windows/IpHlpApi/Interop.ICMP.cs
Original file line number Diff line number Diff line change
Expand Up @@ -13,15 +13,15 @@ internal static partial class IpHlpApi
internal const int IP_STATUS_BASE = 11000;

[StructLayout(LayoutKind.Sequential)]
internal struct IPOptions
internal struct IP_OPTION_INFORMATION
{
internal byte ttl;
internal byte tos;
internal byte flags;
internal byte optionsSize;
internal IntPtr optionsData;

internal IPOptions(PingOptions? options)
internal IP_OPTION_INFORMATION(PingOptions? options)
{
ttl = 128;
tos = 0;
Expand All @@ -42,39 +42,38 @@ internal IPOptions(PingOptions? options)
}

[StructLayout(LayoutKind.Sequential)]
internal struct IcmpEchoReply
internal struct ICMP_ECHO_REPLY
{
internal uint address;
internal uint status;
internal uint roundTripTime;
internal ushort dataSize;
internal ushort reserved;
internal IntPtr data;
internal IPOptions options;
internal IP_OPTION_INFORMATION options;
}

[StructLayout(LayoutKind.Sequential, Pack = 1)]
internal struct Ipv6Address
internal unsafe struct IPV6_ADDRESS_EX
{
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 6)]
internal byte[] Goo;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 16)]
internal ushort port;
internal uint flowinfo;

// Replying address.
internal byte[] Address;
private fixed byte _Address[16];
internal byte[] Address => MemoryMarshal.CreateReadOnlySpan(ref _Address[0], 16).ToArray();

internal uint ScopeID;
}

[StructLayout(LayoutKind.Sequential)]
internal struct Icmp6EchoReply
internal struct ICMPV6_ECHO_REPLY
{
internal Ipv6Address Address;
internal IPV6_ADDRESS_EX Address;
// Reply IP_STATUS.
internal uint Status;
// RTT in milliseconds.
internal uint RoundTripTime;
internal IntPtr data;
// internal IPOptions options;
// internal IntPtr data; data os after tjos
}

internal sealed class SafeCloseIcmpHandle : SafeHandleZeroOrMinusOneIsInvalid
Expand All @@ -101,10 +100,10 @@ protected override bool ReleaseHandle()

[LibraryImport(Interop.Libraries.IpHlpApi, SetLastError = true)]
internal static partial uint IcmpSendEcho2(SafeCloseIcmpHandle icmpHandle, SafeWaitHandle Event, IntPtr apcRoutine, IntPtr apcContext,
uint ipAddress, SafeLocalAllocHandle data, ushort dataSize, ref IPOptions options, SafeLocalAllocHandle replyBuffer, uint replySize, uint timeout);
uint ipAddress, SafeLocalAllocHandle data, ushort dataSize, ref IP_OPTION_INFORMATION options, SafeLocalAllocHandle replyBuffer, uint replySize, uint timeout);

[LibraryImport(Interop.Libraries.IpHlpApi, SetLastError = true)]
internal static partial uint Icmp6SendEcho2(SafeCloseIcmpHandle icmpHandle, SafeWaitHandle Event, IntPtr apcRoutine, IntPtr apcContext,
byte[] sourceSocketAddress, byte[] destSocketAddress, SafeLocalAllocHandle data, ushort dataSize, ref IPOptions options, SafeLocalAllocHandle replyBuffer, uint replySize, uint timeout);
byte[] sourceSocketAddress, byte[] destSocketAddress, SafeLocalAllocHandle data, ushort dataSize, ref IP_OPTION_INFORMATION options, SafeLocalAllocHandle replyBuffer, uint replySize, uint timeout);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -8,14 +8,12 @@ internal static partial class Interop
{
internal static partial class IpHlpApi
{
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)]
public struct IP_ADDR_STRING
[StructLayout(LayoutKind.Sequential)]
public unsafe struct IP_ADDR_STRING
{
public IntPtr Next; // struct _IpAddressList*
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 16)]
public string IpAddress;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 16)]
public string IpMask;
public IP_ADDR_STRING* Next;
public fixed byte IpAddress[16];
public fixed byte IpMask[16];
public uint Context;
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -157,14 +157,7 @@ internal unsafe struct IpAdapterAddresses

private fixed byte _address[MAX_ADAPTER_ADDRESS_LENGTH];
private uint _addressLength;
internal byte[] Address
{
get
{
fixed (byte* pAddress = _address)
return new ReadOnlySpan<byte>(pAddress, (int)_addressLength).ToArray();
}
}
internal byte[] Address => MemoryMarshal.CreateReadOnlySpan<byte>(ref _address[0], (int)_addressLength).ToArray();

internal AdapterFlags flags;
internal uint mtu;
Expand All @@ -173,14 +166,7 @@ internal byte[] Address
internal uint ipv6Index;

private fixed uint _zoneIndices[16];
internal uint[] ZoneIndices
{
get
{
fixed (uint* pZoneIndices = _zoneIndices)
return new ReadOnlySpan<uint>(pZoneIndices, 16).ToArray();
}
}
internal uint[] ZoneIndices => MemoryMarshal.CreateReadOnlySpan<uint>(ref _zoneIndices[0], 16).ToArray();

internal IntPtr firstPrefix;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,61 +12,113 @@ namespace System.Net.NetworkInformation
internal static class HostInformationPal
{
// Changing this information requires a reboot, so it's safe to cache.
private static Interop.IpHlpApi.FIXED_INFO s_fixedInfo;
private static bool s_fixedInfoInitialized;
private static string? s_hostName;
private static string? s_domainName;
private static uint s_nodeType;
private static string? s_scopeId;
private static bool s_enableRouting;
private static bool s_enableProxy;
private static bool s_enableDns;

private static volatile bool s_initialized;
private static object s_syncObject = new object();

public static string GetHostName()
{
return FixedInfo.hostName;
EnsureInitialized();
return s_hostName!;
}

public static string GetDomainName()
{
return FixedInfo.domainName;
EnsureInitialized();
return s_domainName!;
}

public static uint GetNodeType()
{
EnsureInitialized();
return s_nodeType;
}

public static string GetScopeId()
{
EnsureInitialized();
return s_scopeId!;
}

public static bool GetEnableRouting()
{
EnsureInitialized();
return s_enableRouting;
}

private static unsafe Interop.IpHlpApi.FIXED_INFO GetFixedInfo()
public static bool GetEnableProxy()
{
uint size = 0;
Interop.IpHlpApi.FIXED_INFO fixedInfo = default;
EnsureInitialized();
return s_enableProxy;
}

// First we need to get the size of the buffer
uint result = Interop.IpHlpApi.GetNetworkParams(IntPtr.Zero, &size);
public static bool GetEnableDns()
{
EnsureInitialized();
return s_enableDns;
}

while (result == Interop.IpHlpApi.ERROR_BUFFER_OVERFLOW)
private static void EnsureInitialized()
{
if (!s_initialized)
Initialize();
}

private static unsafe void Initialize()
{
lock (s_syncObject)
{
IntPtr buffer = Marshal.AllocHGlobal((int)size);
try
if (s_initialized)
return;

uint size = 0;

// First we need to get the size of the buffer
uint result = Interop.IpHlpApi.GetNetworkParams(IntPtr.Zero, &size);

while (result == Interop.IpHlpApi.ERROR_BUFFER_OVERFLOW)
{
result = Interop.IpHlpApi.GetNetworkParams(buffer, &size);
if (result == Interop.IpHlpApi.ERROR_SUCCESS)
IntPtr buffer = Marshal.AllocHGlobal((int)size);
try
{
fixedInfo = Marshal.PtrToStructure<Interop.IpHlpApi.FIXED_INFO>(buffer);
result = Interop.IpHlpApi.GetNetworkParams(buffer, &size);
if (result == Interop.IpHlpApi.ERROR_SUCCESS)
{
Interop.IpHlpApi.FIXED_INFO* pFixedInfo = (Interop.IpHlpApi.FIXED_INFO*)buffer;

s_hostName = pFixedInfo->HostName;
s_domainName = pFixedInfo->DomainName;

s_hostName = pFixedInfo->HostName;
s_domainName = pFixedInfo->DomainName;
s_nodeType = pFixedInfo->nodeType;
s_scopeId = pFixedInfo->ScopeId;
s_enableRouting = pFixedInfo->enableRouting != 0;
s_enableProxy = pFixedInfo->enableProxy != 0;
s_enableDns = pFixedInfo->enableDns != 0;

s_initialized = true;
}
}
finally
{
Marshal.FreeHGlobal(buffer);
}
}
finally

// If the result include there being no information, we'll still throw
if (result != Interop.IpHlpApi.ERROR_SUCCESS)
{
Marshal.FreeHGlobal(buffer);
throw new Win32Exception((int)result);
}
}

// If the result include there being no information, we'll still throw
if (result != Interop.IpHlpApi.ERROR_SUCCESS)
{
throw new Win32Exception((int)result);
}

return fixedInfo;
}

public static ref readonly Interop.IpHlpApi.FIXED_INFO FixedInfo
{
get
{
LazyInitializer.EnsureInitialized(ref s_fixedInfo, ref s_fixedInfoInitialized, ref s_syncObject, () => GetFixedInfo());
return ref s_fixedInfo;
}
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ public override string HostName
{
get
{
return HostInformationPal.FixedInfo.hostName;
return HostInformationPal.GetHostName();
}
}

Expand All @@ -28,7 +28,7 @@ public override string DomainName
{
get
{
return HostInformationPal.FixedInfo.domainName;
return HostInformationPal.GetDomainName();
}
}

Expand All @@ -48,7 +48,7 @@ public override NetBiosNodeType NodeType
{
get
{
return (NetBiosNodeType)HostInformationPal.FixedInfo.nodeType;
return (NetBiosNodeType)HostInformationPal.GetNodeType();
}
}

Expand All @@ -57,7 +57,7 @@ public override string DhcpScopeName
{
get
{
return HostInformationPal.FixedInfo.scopeId;
return HostInformationPal.GetScopeId();
}
}

Expand All @@ -66,7 +66,7 @@ public override bool IsWinsProxy
{
get
{
return (HostInformationPal.FixedInfo.enableProxy);
return HostInformationPal.GetEnableProxy();
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,11 +26,11 @@ internal sealed class SystemIPInterfaceProperties : IPInterfaceProperties
private readonly GatewayIPAddressInformationCollection _gatewayAddresses;
private readonly InternalIPAddressCollection _dhcpServers;

internal SystemIPInterfaceProperties(in Interop.IpHlpApi.FIXED_INFO fixedInfo, in Interop.IpHlpApi.IpAdapterAddresses ipAdapterAddresses)
internal SystemIPInterfaceProperties(in Interop.IpHlpApi.IpAdapterAddresses ipAdapterAddresses)
{
_adapterFlags = ipAdapterAddresses.flags;
_dnsSuffix = ipAdapterAddresses.DnsSuffix;
_dnsEnabled = fixedInfo.enableDns;
_dnsEnabled = HostInformationPal.GetEnableDns();
_dynamicDnsEnabled = ((ipAdapterAddresses.flags & Interop.IpHlpApi.AdapterFlags.DnsEnabled) > 0);

_multicastAddresses = SystemMulticastIPAddressInformation.ToMulticastIpAddressInformationCollection(
Expand Down Expand Up @@ -58,7 +58,7 @@ internal SystemIPInterfaceProperties(in Interop.IpHlpApi.FIXED_INFO fixedInfo, i

if ((_adapterFlags & Interop.IpHlpApi.AdapterFlags.IPv4Enabled) != 0)
{
_ipv4Properties = new SystemIPv4InterfaceProperties(fixedInfo, ipAdapterAddresses);
_ipv4Properties = new SystemIPv4InterfaceProperties(ipAdapterAddresses);
}

if ((_adapterFlags & Interop.IpHlpApi.AdapterFlags.IPv6Enabled) != 0)
Expand Down
Loading