Imported Upstream version 5.0.0.42

Former-commit-id: fd56571888259555122d8a0f58c68838229cea2b
This commit is contained in:
Xamarin Public Jenkins (auto-signing)
2017-04-10 11:41:01 +00:00
parent 1190d13a04
commit 6bdd276d05
19939 changed files with 3099680 additions and 93811 deletions

View File

@@ -34,13 +34,11 @@ using System.Runtime.InteropServices;
namespace System.Net.NetworkInformation {
#if !MOBILE
#if WIN_PLATFORM
class Win32IPAddressCollection : IPAddressCollection
{
public static readonly Win32IPAddressCollection Empty = new Win32IPAddressCollection (IntPtr.Zero);
bool is_readonly;
// for static methods
Win32IPAddressCollection ()
{
@@ -50,7 +48,6 @@ namespace System.Net.NetworkInformation {
{
foreach (IntPtr head in heads)
AddSubsequentlyString (head);
is_readonly = true;
}
public Win32IPAddressCollection (params Win32_IP_ADDR_STRING [] al)
@@ -58,10 +55,9 @@ namespace System.Net.NetworkInformation {
foreach (Win32_IP_ADDR_STRING a in al) {
if (String.IsNullOrEmpty (a.IpAddress))
continue;
Add (IPAddress.Parse (a.IpAddress));
InternalAdd (IPAddress.Parse (a.IpAddress));
AddSubsequentlyString (a.Next);
}
is_readonly = true;
}
public static Win32IPAddressCollection FromAnycast (IntPtr ptr)
@@ -70,9 +66,8 @@ namespace System.Net.NetworkInformation {
Win32_IP_ADAPTER_ANYCAST_ADDRESS a;
for (IntPtr p = ptr; p != IntPtr.Zero; p = a.Next) {
a = (Win32_IP_ADAPTER_ANYCAST_ADDRESS) Marshal.PtrToStructure (p, typeof (Win32_IP_ADAPTER_ANYCAST_ADDRESS));
c.Add (a.Address.GetIPAddress ());
c.InternalAdd (a.Address.GetIPAddress ());
}
c.is_readonly = true;
return c;
}
@@ -84,9 +79,8 @@ namespace System.Net.NetworkInformation {
a = (Win32_IP_ADAPTER_DNS_SERVER_ADDRESS) Marshal.PtrToStructure (p, typeof (Win32_IP_ADAPTER_DNS_SERVER_ADDRESS));
// FIXME: It somehow fails here. Looks like there is something wrong.
//if (a.Address.Sockaddr == IntPtr.Zero) throw new Exception ("pointer " + p + " a.length " + a.Address.SockaddrLength);
c.Add (a.Address.GetIPAddress ());
c.InternalAdd (a.Address.GetIPAddress ());
}
c.is_readonly = true;
return c;
}
@@ -95,13 +89,9 @@ namespace System.Net.NetworkInformation {
Win32_IP_ADDR_STRING a;
for (IntPtr p = head; p != IntPtr.Zero; p = a.Next) {
a = (Win32_IP_ADDR_STRING) Marshal.PtrToStructure (p, typeof (Win32_IP_ADDR_STRING));
Add (IPAddress.Parse (a.IpAddress));
InternalAdd (IPAddress.Parse (a.IpAddress));
}
}
public override bool IsReadOnly {
get { return is_readonly; }
}
}
#endif
}

View File

@@ -351,7 +351,7 @@ namespace System.Net.NetworkInformation {
}
}
#if !MOBILE
#if WIN_PLATFORM
class Win32IPGlobalProperties : IPGlobalProperties
{
public const int AF_INET = 2;
@@ -487,7 +487,7 @@ namespace System.Net.NetworkInformation {
public override IcmpV4Statistics GetIcmpV4Statistics ()
{
if (!Socket.SupportsIPv4)
if (!Socket.OSSupportsIPv4)
throw new NetworkInformationException ();
Win32_MIBICMPINFO stats;
GetIcmpStatistics (out stats, AF_INET);
@@ -505,7 +505,7 @@ namespace System.Net.NetworkInformation {
public override IPGlobalStatistics GetIPv4GlobalStatistics ()
{
if (!Socket.SupportsIPv4)
if (!Socket.OSSupportsIPv4)
throw new NetworkInformationException ();
Win32_MIB_IPSTATS stats;
GetIpStatisticsEx (out stats, AF_INET);
@@ -523,7 +523,7 @@ namespace System.Net.NetworkInformation {
public override TcpStatistics GetTcpIPv4Statistics ()
{
if (!Socket.SupportsIPv4)
if (!Socket.OSSupportsIPv4)
throw new NetworkInformationException ();
Win32_MIB_TCPSTATS stats;
GetTcpStatisticsEx (out stats, AF_INET);
@@ -541,7 +541,7 @@ namespace System.Net.NetworkInformation {
public override UdpStatistics GetUdpIPv4Statistics ()
{
if (!Socket.SupportsIPv4)
if (!Socket.OSSupportsIPv4)
throw new NetworkInformationException ();
Win32_MIB_UDPSTATS stats;
GetUdpStatisticsEx (out stats, AF_INET);
@@ -558,23 +558,23 @@ namespace System.Net.NetworkInformation {
}
public override string DhcpScopeName {
get { return Win32_FIXED_INFO.Instance.ScopeId; }
get { return Win32NetworkInterface.FixedInfo.ScopeId; }
}
public override string DomainName {
get { return Win32_FIXED_INFO.Instance.DomainName; }
get { return Win32NetworkInterface.FixedInfo.DomainName; }
}
public override string HostName {
get { return Win32_FIXED_INFO.Instance.HostName; }
get { return Win32NetworkInterface.FixedInfo.HostName; }
}
public override bool IsWinsProxy {
get { return Win32_FIXED_INFO.Instance.EnableProxy != 0; }
get { return Win32NetworkInterface.FixedInfo.EnableProxy != 0; }
}
public override NetBiosNodeType NodeType {
get { return Win32_FIXED_INFO.Instance.NodeType; }
get { return Win32NetworkInterface.FixedInfo.NodeType; }
}
// PInvokes

View File

@@ -113,7 +113,7 @@ namespace System.Net.NetworkInformation {
}
}
#if !MOBILE
#if WIN_PLATFORM
class Win32IPGlobalStatistics : IPGlobalStatistics
{
Win32_MIB_IPSTATS info;

View File

@@ -41,8 +41,6 @@ namespace System.Net.NetworkInformation {
protected UnixNetworkInterface iface;
List <IPAddress> addresses;
IPAddressCollection dns_servers;
string dns_suffix;
DateTime last_parse;
public UnixIPInterfaceProperties (UnixNetworkInterface iface, List <IPAddress> addresses)
{
@@ -83,6 +81,10 @@ namespace System.Net.NetworkInformation {
#else
static Regex ns = new Regex (@"\s*nameserver\s+(?<address>.*)");
static Regex search = new Regex (@"\s*search\s+(?<domain>.*)");
string dns_suffix;
DateTime last_parse;
void ParseResolvConf ()
{
try {
@@ -324,7 +326,7 @@ namespace System.Net.NetworkInformation {
}
}
#if !MOBILE
#if WIN_PLATFORM
class Win32IPInterfaceProperties2 : IPInterfaceProperties
{
readonly Win32_IP_ADAPTER_ADDRESSES addr;
@@ -340,13 +342,13 @@ namespace System.Net.NetworkInformation {
public override IPv4InterfaceProperties GetIPv4Properties ()
{
Win32_IP_ADAPTER_INFO v4info = Win32NetworkInterface2.GetAdapterInfoByIndex (mib4.Index);
return v4info != null ? new Win32IPv4InterfaceProperties (v4info, mib4) : null;
return new Win32IPv4InterfaceProperties (v4info, mib4);
}
public override IPv6InterfaceProperties GetIPv6Properties ()
{
Win32_IP_ADAPTER_INFO v6info = Win32NetworkInterface2.GetAdapterInfoByIndex (mib6.Index);
return v6info != null ? new Win32IPv6InterfaceProperties (mib6) : null;
return new Win32IPv6InterfaceProperties (mib6);
}
public override IPAddressInformationCollection AnycastAddresses {
@@ -371,7 +373,11 @@ namespace System.Net.NetworkInformation {
get {
Win32_IP_ADAPTER_INFO v4info = Win32NetworkInterface2.GetAdapterInfoByIndex (mib4.Index);
// FIXME: should ipv6 DhcpServer be considered?
return v4info != null ? new Win32IPAddressCollection (v4info.DhcpServer) : Win32IPAddressCollection.Empty;
try {
return new Win32IPAddressCollection (v4info.DhcpServer);
} catch (IndexOutOfRangeException) {
return Win32IPAddressCollection.Empty;
}
}
}
@@ -385,18 +391,17 @@ namespace System.Net.NetworkInformation {
public override GatewayIPAddressInformationCollection GatewayAddresses {
get {
Win32_IP_ADAPTER_INFO v4info = Win32NetworkInterface2.GetAdapterInfoByIndex (mib4.Index);
// FIXME: should ipv6 DhcpServer be considered?
var col = new GatewayIPAddressInformationCollection ();
if (v4info != null) {
try {
Win32_IP_ADAPTER_INFO v4info = Win32NetworkInterface2.GetAdapterInfoByIndex (mib4.Index);
// FIXME: should ipv6 DhcpServer be considered?
var a = v4info.GatewayList;
if (!String.IsNullOrEmpty (a.IpAddress)) {
col.InternalAdd(new SystemGatewayIPAddressInformation(IPAddress.Parse (a.IpAddress)));
AddSubsequently (a.Next, col);
}
}
} catch (IndexOutOfRangeException) {}
return col;
}
}
@@ -411,7 +416,7 @@ namespace System.Net.NetworkInformation {
}
public override bool IsDnsEnabled {
get { return Win32_FIXED_INFO.Instance.EnableDns != 0; }
get { return Win32NetworkInterface.FixedInfo.EnableDns != 0; }
}
public override bool IsDynamicDnsEnabled {
@@ -438,28 +443,36 @@ namespace System.Net.NetworkInformation {
public override UnicastIPAddressInformationCollection UnicastAddresses {
get {
Win32_IP_ADAPTER_INFO ai = Win32NetworkInterface2.GetAdapterInfoByIndex (mib4.Index);
// FIXME: should ipv6 DhcpServer be considered?
return ai != null ? Win32FromUnicast ((int) ai.Index, addr.FirstUnicastAddress) : new UnicastIPAddressInformationCollection ();
try {
Win32_IP_ADAPTER_INFO ai = Win32NetworkInterface2.GetAdapterInfoByIndex (mib4.Index);
// FIXME: should ipv6 DhcpServer be considered?
return Win32FromUnicast (addr.FirstUnicastAddress);
} catch (IndexOutOfRangeException) {
return new UnicastIPAddressInformationCollection ();
}
}
}
static UnicastIPAddressInformationCollection Win32FromUnicast (int ifIndex, IntPtr ptr)
static UnicastIPAddressInformationCollection Win32FromUnicast (IntPtr ptr)
{
UnicastIPAddressInformationCollection c = new UnicastIPAddressInformationCollection ();
Win32_IP_ADAPTER_UNICAST_ADDRESS a;
for (IntPtr p = ptr; p != IntPtr.Zero; p = a.Next) {
a = (Win32_IP_ADAPTER_UNICAST_ADDRESS) Marshal.PtrToStructure (p, typeof (Win32_IP_ADAPTER_UNICAST_ADDRESS));
c.InternalAdd (new Win32UnicastIPAddressInformation (ifIndex, a));
c.InternalAdd (new Win32UnicastIPAddressInformation (a));
}
return c;
}
public override IPAddressCollection WinsServersAddresses {
get {
Win32_IP_ADAPTER_INFO v4info = Win32NetworkInterface2.GetAdapterInfoByIndex (mib4.Index);
// FIXME: should ipv6 DhcpServer be considered?
return v4info != null ? new Win32IPAddressCollection (v4info.PrimaryWinsServer, v4info.SecondaryWinsServer) : Win32IPAddressCollection.Empty;
try {
Win32_IP_ADAPTER_INFO v4info = Win32NetworkInterface2.GetAdapterInfoByIndex (mib4.Index);
// FIXME: should ipv6 DhcpServer be considered?
return new Win32IPAddressCollection (v4info.PrimaryWinsServer, v4info.SecondaryWinsServer);
} catch (IndexOutOfRangeException) {
return Win32IPAddressCollection.Empty;
}
}
}

View File

@@ -123,7 +123,7 @@ namespace System.Net.NetworkInformation {
}
}
#if !MOBILE
#if WIN_PLATFORM
sealed class Win32IPv4InterfaceProperties : IPv4InterfaceProperties
{
[DllImport ("iphlpapi.dll")]
@@ -165,7 +165,7 @@ namespace System.Net.NetworkInformation {
public override bool IsForwardingEnabled {
// Is it the right answer? In Vista there is MIB_IPINTERFACEROW.ForwardingEnabled, but not in former versions.
get { return Win32_FIXED_INFO.Instance.EnableRouting != 0; }
get { return Win32NetworkInterface.FixedInfo.EnableRouting != 0; }
}
public override int Mtu {

View File

@@ -28,7 +28,7 @@
// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
//
namespace System.Net.NetworkInformation {
#if !MOBILE
#if WIN_PLATFORM
class Win32IPv4InterfaceStatistics : IPv4InterfaceStatistics
{
Win32_MIB_IFROW info;

View File

@@ -27,7 +27,7 @@
// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
//
namespace System.Net.NetworkInformation {
#if !MOBILE
#if WIN_PLATFORM
class Win32IPv6InterfaceProperties : IPv6InterfaceProperties
{
Win32_MIB_IFROW mib;

View File

@@ -124,7 +124,7 @@ namespace System.Net.NetworkInformation {
}
}
#if !MOBILE
#if WIN_PLATFORM
class Win32IcmpV4Statistics : IcmpV4Statistics
{
Win32_MIBICMPSTATS iin, iout;

View File

@@ -162,7 +162,7 @@ namespace System.Net.NetworkInformation {
public const int RouterRenumbering = 138;
}
#if !MOBILE
#if WIN_PLATFORM
class Win32IcmpV6Statistics : IcmpV6Statistics
{
Win32_MIBICMPSTATS_EX iin, iout;

View File

@@ -299,9 +299,7 @@ namespace System.Net.NetworkInformation {
}
}
#if MONOTOUCH || MOBILE_STATIC
[MonoTouch.MonoPInvokeCallback (typeof (SCNetworkReachabilityCallback))]
#endif
[Mono.Util.MonoPInvokeCallback (typeof (SCNetworkReachabilityCallback))]
static void HandleCallback (IntPtr reachability, NetworkReachabilityFlags flags, IntPtr info)
{
if (info == IntPtr.Zero)

View File

@@ -435,31 +435,34 @@ namespace System.Net.NetworkInformation {
}
}
#if !MOBILE
#if WIN_PLATFORM
class Win32NetworkInterfaceAPI : NetworkInterfaceFactory
{
[DllImport ("iphlpapi.dll", SetLastError = true)]
static extern int GetAdaptersAddresses (uint family, uint flags, IntPtr reserved, byte [] info, ref int size);
private const string IPHLPAPI = "iphlpapi.dll";
unsafe static Win32_IP_ADAPTER_ADDRESSES [] GetAdaptersAddresses ()
[DllImport (IPHLPAPI, SetLastError = true)]
static extern int GetAdaptersAddresses (uint family, uint flags, IntPtr reserved, IntPtr info, ref int size);
[DllImport (IPHLPAPI)]
static extern uint GetBestInterfaceEx (byte[] ipAddress, out int index);
static Win32_IP_ADAPTER_ADDRESSES [] GetAdaptersAddresses ()
{
byte [] bytes = null;
IntPtr ptr = IntPtr.Zero;
int len = 0;
GetAdaptersAddresses (0, 0, IntPtr.Zero, bytes, ref len);
bytes = new byte [len];
int ret = GetAdaptersAddresses (0, 0, IntPtr.Zero, bytes, ref len);
GetAdaptersAddresses (0, 0, IntPtr.Zero, ptr, ref len);
ptr = Marshal.AllocHGlobal(len);
int ret = GetAdaptersAddresses (0, 0, IntPtr.Zero, ptr, ref len);
if (ret != 0)
throw new NetworkInformationException (ret);
List<Win32_IP_ADAPTER_ADDRESSES> l = new List<Win32_IP_ADAPTER_ADDRESSES> ();
fixed (byte* ptr = bytes) {
Win32_IP_ADAPTER_ADDRESSES info;
for (IntPtr p = (IntPtr) ptr; p != IntPtr.Zero; p = info.Next) {
info = new Win32_IP_ADAPTER_ADDRESSES ();
Marshal.PtrToStructure (p, info);
l.Add (info);
}
Win32_IP_ADAPTER_ADDRESSES info;
for (IntPtr p = ptr; p != IntPtr.Zero; p = info.Next) {
info = Marshal.PtrToStructure<Win32_IP_ADAPTER_ADDRESSES> (p);
l.Add (info);
}
return l.ToArray ();
}
@@ -473,9 +476,20 @@ namespace System.Net.NetworkInformation {
return ret;
}
private static int GetBestInterfaceForAddress (IPAddress addr) {
int index;
SocketAddress address = new SocketAddress (addr);
int error = (int) GetBestInterfaceEx (address.m_Buffer, out index);
if (error != 0) {
throw new NetworkInformationException (error);
}
return index;
}
public override int GetLoopbackInterfaceIndex ()
{
throw new NotImplementedException ();
return GetBestInterfaceForAddress (IPAddress.Loopback);
}
public override IPAddress GetNetMask (IPAddress address)
@@ -494,7 +508,6 @@ namespace System.Net.NetworkInformation {
#if MONOTOUCH || XAMMAC
return new MacOsNetworkInterfaceAPI ();
#else
Version windowsVer51 = new Version (5, 1);
bool runningOnUnix = (Environment.OSVersion.Platform == PlatformID.Unix);
if (runningOnUnix) {
@@ -504,7 +517,8 @@ namespace System.Net.NetworkInformation {
return new LinuxNetworkInterfaceAPI ();
}
#if !MOBILE
#if WIN_PLATFORM
Version windowsVer51 = new Version (5, 1);
if (Environment.OSVersion.Version >= windowsVer51)
return new Win32NetworkInterfaceAPI ();
#endif
@@ -617,13 +631,13 @@ namespace System.Net.NetworkInformation {
#if MONODROID
[DllImport ("__Internal")]
protected static extern int _monodroid_get_android_api_level ();
static extern int _monodroid_get_android_api_level ();
[DllImport ("__Internal")]
protected static extern bool _monodroid_get_network_interface_up_state (string ifname, ref bool is_up);
static extern bool _monodroid_get_network_interface_up_state (string ifname, ref bool is_up);
[DllImport ("__Internal")]
protected static extern bool _monodroid_get_network_interface_supports_multicast (string ifname, ref bool supports_multicast);
static extern bool _monodroid_get_network_interface_supports_multicast (string ifname, ref bool supports_multicast);
bool android_use_java_api;
#endif
@@ -791,11 +805,11 @@ namespace System.Net.NetworkInformation {
}
}
#if !MOBILE
#if WIN_PLATFORM
class Win32NetworkInterface2 : NetworkInterface
{
[DllImport ("iphlpapi.dll", SetLastError = true)]
static extern int GetAdaptersInfo (byte [] info, ref int size);
static extern int GetAdaptersInfo (IntPtr info, ref int size);
[DllImport ("iphlpapi.dll", SetLastError = true)]
static extern int GetIfEntry (ref Win32_MIB_IFROW row);
@@ -805,28 +819,25 @@ namespace System.Net.NetworkInformation {
foreach (Win32_IP_ADAPTER_INFO info in GetAdaptersInfo ())
if (info.Index == index)
return info;
return null;
throw new IndexOutOfRangeException ("No adapter found for index " + index);
}
unsafe static Win32_IP_ADAPTER_INFO [] GetAdaptersInfo ()
static Win32_IP_ADAPTER_INFO [] GetAdaptersInfo ()
{
byte [] bytes = null;
int len = 0;
GetAdaptersInfo (bytes, ref len);
bytes = new byte [len];
int ret = GetAdaptersInfo (bytes, ref len);
IntPtr ptr = IntPtr.Zero;
GetAdaptersInfo (ptr, ref len);
ptr = Marshal.AllocHGlobal(len);
int ret = GetAdaptersInfo (ptr, ref len);
if (ret != 0)
throw new NetworkInformationException (ret);
List<Win32_IP_ADAPTER_INFO> l = new List<Win32_IP_ADAPTER_INFO> ();
fixed (byte* ptr = bytes) {
Win32_IP_ADAPTER_INFO info;
for (IntPtr p = (IntPtr) ptr; p != IntPtr.Zero; p = info.Next) {
info = new Win32_IP_ADAPTER_INFO ();
Marshal.PtrToStructure (p, info);
l.Add (info);
}
Win32_IP_ADAPTER_INFO info;
for (IntPtr p = ptr; p != IntPtr.Zero; p = info.Next) {
info = Marshal.PtrToStructure<Win32_IP_ADAPTER_INFO> (p);
l.Add (info);
}
return l.ToArray ();
}

View File

@@ -71,6 +71,7 @@ namespace System.Net.NetworkInformation {
#endif
};
static readonly string PingBinPath;
static bool canSendPrivileged;
#endif
const int default_timeout = 4000; // 4 sec.
ushort identifier;
@@ -80,7 +81,6 @@ namespace System.Net.NetworkInformation {
const UInt32 linux_cap_version = 0x20071026;
static readonly byte [] default_buffer = new byte [0];
static bool canSendPrivileged;
BackgroundWorker worker;
@@ -207,11 +207,14 @@ namespace System.Net.NetworkInformation {
return Send (addresses [0], timeout, buffer, options);
}
static IPAddress GetNonLoopbackIP ()
static IPAddress GetNonLoopbackIPV4 ()
{
#pragma warning disable 618
foreach (IPAddress addr in Dns.GetHostByName (Dns.GetHostName ()).AddressList)
if (!IPAddress.IsLoopback (addr))
if (!IPAddress.IsLoopback (addr) && addr.AddressFamily == AddressFamily.InterNetwork)
return addr;
#pragma warning restore 618
throw new InvalidOperationException ("Could not resolve non-loopback IP address for localhost");
}
@@ -240,7 +243,7 @@ namespace System.Net.NetworkInformation {
private PingReply SendPrivileged (IPAddress address, int timeout, byte [] buffer, PingOptions options)
{
IPEndPoint target = new IPEndPoint (address, 0);
IPEndPoint client = new IPEndPoint (GetNonLoopbackIP (), 0);
IPEndPoint client = new IPEndPoint (GetNonLoopbackIPV4 (), 0);
// FIXME: support IPv6
using (Socket s = new Socket (AddressFamily.InterNetwork, SocketType.Raw, ProtocolType.Icmp)) {
@@ -262,12 +265,12 @@ namespace System.Net.NetworkInformation {
bytes = new byte [100];
do {
EndPoint endpoint = client;
int error = 0;
int rc = s.ReceiveFrom_nochecks_exc (bytes, 0, 100, SocketFlags.None,
ref endpoint, false, out error);
SocketError error = 0;
int rc = s.ReceiveFrom (bytes, 0, 100, SocketFlags.None,
ref endpoint, out error);
if (error != 0) {
if (error == (int) SocketError.TimedOut) {
if (error != SocketError.Success) {
if (error == SocketError.TimedOut) {
return new PingReply (null, new byte [0], options, 0, IPStatus.TimedOut);
}
throw new NotSupportedException (String.Format ("Unexpected socket error during ping request: {0}", error));

View File

@@ -88,7 +88,7 @@ namespace System.Net.NetworkInformation {
}
}
#if !MOBILE
#if WIN_PLATFORM
class Win32TcpStatistics : TcpStatistics
{
Win32_MIB_TCPSTATS info;

View File

@@ -61,7 +61,7 @@ namespace System.Net.NetworkInformation {
}
}
#if !MOBILE
#if WIN_PLATFORM
class Win32UdpStatistics : UdpStatistics
{
Win32_MIB_UDPSTATS info;

View File

@@ -30,18 +30,23 @@
using System;
using System.Runtime.InteropServices;
using System.Net.Sockets;
using System.Diagnostics.Contracts;
namespace System.Net.NetworkInformation {
#if !MOBILE
#if WIN_PLATFORM
class Win32UnicastIPAddressInformation : UnicastIPAddressInformation
{
int if_index;
Win32_IP_ADAPTER_UNICAST_ADDRESS info;
IPAddress ipv4Mask;
public Win32UnicastIPAddressInformation (int ifIndex, Win32_IP_ADAPTER_UNICAST_ADDRESS info)
public Win32UnicastIPAddressInformation (Win32_IP_ADAPTER_UNICAST_ADDRESS info)
{
this.if_index = ifIndex;
this.info = info;
IPAddress ipAddress = info.Address.GetIPAddress ();
// IPv6 returns 0.0.0.0 for consistancy with XP
if (ipAddress.AddressFamily == AddressFamily.InterNetwork) {
ipv4Mask = PrefixLengthToSubnetMask (info.OnLinkPrefixLength, ipAddress.AddressFamily);
}
}
public override IPAddress Address {
@@ -74,27 +79,15 @@ namespace System.Net.NetworkInformation {
get { return info.DadState; }
}
public override IPAddress IPv4Mask {
public override IPAddress IPv4Mask{
get {
Win32_IP_ADAPTER_INFO ai = Win32NetworkInterface2.GetAdapterInfoByIndex (if_index);
if (ai == null)
throw new Exception ("huh? " + if_index);
if (this.Address == null)
return null;
string expected = this.Address.ToString ();
unsafe {
Win32_IP_ADDR_STRING p = ai.IpAddressList;
while (true) {
if (p.IpAddress == expected)
return IPAddress.Parse (p.IpMask);
if (p.Next == IntPtr.Zero)
break;
p = (Win32_IP_ADDR_STRING) Marshal.PtrToStructure (p.Next, typeof (Win32_IP_ADDR_STRING));
}
// Or whatever it should be...
return null;
// The IPv6 equivilant was never available on XP, and we've kept this behavior for legacy reasons.
// For IPv6 use PrefixLength instead.
if (Address.AddressFamily != AddressFamily.InterNetwork) {
return IPAddress.Any;
}
return ipv4Mask;
}
}
@@ -105,6 +98,28 @@ namespace System.Net.NetworkInformation {
public override SuffixOrigin SuffixOrigin {
get { return info.SuffixOrigin; }
}
// Convert a CIDR prefix length to a subnet mask "255.255.255.0" format
private static IPAddress PrefixLengthToSubnetMask (byte prefixLength, AddressFamily family) {
Contract.Requires ((0 <= prefixLength) && (prefixLength <= 126));
Contract.Requires ((family == AddressFamily.InterNetwork) || (family == AddressFamily.InterNetworkV6));
byte[] addressBytes;
if (family == AddressFamily.InterNetwork) {
addressBytes = new byte [4];
} else { // v6
addressBytes = new byte [16];
}
Contract.Assert (prefixLength < (addressBytes.Length * 8));
// Enable bits one at a time from left/high to right/low
for (int bit = 0; bit < prefixLength; bit++) {
addressBytes [bit / 8] |= (byte) (0x80 >> (bit % 8));
}
return new IPAddress (addressBytes);
}
}
#endif

View File

@@ -33,52 +33,48 @@ using System.Text;
namespace System.Net.NetworkInformation
{
class Win32NetworkInterface {
// Can't have unresolvable pinvokes on ios
#if WIN_PLATFORM
[DllImport ("iphlpapi.dll", SetLastError = true)]
static extern int GetNetworkParams (IntPtr ptr, ref int size);
#endif
static Win32_FIXED_INFO fixedInfo;
static bool initialized = false;
public static Win32_FIXED_INFO FixedInfo {
get {
if (!initialized) {
#if WIN_PLATFORM
int len = 0;
IntPtr ptr = IntPtr.Zero;
GetNetworkParams (ptr, ref len);
ptr = Marshal.AllocHGlobal(len);
GetNetworkParams (ptr, ref len);
fixedInfo = Marshal.PtrToStructure<Win32_FIXED_INFO> (ptr);
#else
throw new NotImplementedException ();
#endif
initialized = true;
}
return fixedInfo;
}
}
}
// They are mostly defined in iptypes.h (included by iphlpapi.h).
// grep around /usr/include/w32api/* for identifiers you are curious.
[StructLayout (LayoutKind.Sequential)]
class Win32_FIXED_INFO
struct Win32_FIXED_INFO
{
// Can't have unresolvable pinvokes on ios
#if !MOBILE
[DllImport ("iphlpapi.dll", SetLastError = true)]
static extern int GetNetworkParams (byte [] bytes, ref int size);
#endif
static Win32_FIXED_INFO fixed_info;
public static Win32_FIXED_INFO Instance {
get {
if (fixed_info == null)
fixed_info = GetInstance ();
return fixed_info;
}
}
static Win32_FIXED_INFO GetInstance ()
{
#if !MOBILE
int len = 0;
byte [] bytes = null;
GetNetworkParams (null, ref len);
bytes = new byte [len];
GetNetworkParams (bytes, ref len);
Win32_FIXED_INFO info = new Win32_FIXED_INFO ();
unsafe {
fixed (byte* ptr = bytes) {
Marshal.PtrToStructure ((IntPtr) ptr, info);
}
}
return info;
#else
throw new NotImplementedException ();
#endif
}
const int MAX_HOSTNAME_LEN = 128;
const int MAX_DOMAIN_NAME_LEN = 128;
const int MAX_SCOPE_ID_LEN = 256;
[MarshalAs (UnmanagedType.ByValTStr, SizeConst = MAX_HOSTNAME_LEN + 4)]
public string HostName;
[MarshalAs (UnmanagedType.ByValTStr, SizeConst = MAX_DOMAIN_NAME_LEN + 4)]
@@ -105,7 +101,7 @@ namespace System.Net.NetworkInformation
}
[StructLayout (LayoutKind.Sequential, CharSet = CharSet.Unicode)]
class Win32_IP_ADAPTER_ADDRESSES {
struct Win32_IP_ADAPTER_ADDRESSES {
public AlignmentUnion Alignment;
public IntPtr Next; // to Win32_IP_ADAPTER_ADDRESSES
[MarshalAs (UnmanagedType.LPStr)]
@@ -151,7 +147,7 @@ namespace System.Net.NetworkInformation
}
[StructLayout (LayoutKind.Sequential)]
class Win32_IP_ADAPTER_INFO
struct Win32_IP_ADAPTER_INFO
{
const int MAX_ADAPTER_NAME_LENGTH = 256;
const int MAX_ADAPTER_DESCRIPTION_LENGTH = 128;