X-Git-Url: http://wien.tomnetworks.com/gitweb/?a=blobdiff_plain;f=mcs%2Fclass%2FSystem%2FSystem.Net.NetworkInformation%2FNetworkInterface.cs;h=fedf95dbb4d323b3fda4dae6266c6a27f99bb15a;hb=42874b6479cf103ca2e044b95c27a2edbb21d75c;hp=ece698af2b45ee2714a2c52e822ce4a09c90083d;hpb=883a0ae745bf33b35d44bb730d5714936a2141f7;p=mono.git diff --git a/mcs/class/System/System.Net.NetworkInformation/NetworkInterface.cs b/mcs/class/System/System.Net.NetworkInformation/NetworkInterface.cs index ece698af2b4..fedf95dbb4d 100644 --- a/mcs/class/System/System.Net.NetworkInformation/NetworkInterface.cs +++ b/mcs/class/System/System.Net.NetworkInformation/NetworkInterface.cs @@ -82,6 +82,22 @@ namespace System.Net.NetworkInformation { { internal abstract class UnixNetworkInterfaceAPI : NetworkInterfaceFactory { +#if ORBIS + public static int if_nametoindex(string ifname) + { + throw new PlatformNotSupportedException (); + } + + protected static int getifaddrs (out IntPtr ifap) + { + throw new PlatformNotSupportedException (); + } + + protected static void freeifaddrs (IntPtr ifap) + { + throw new PlatformNotSupportedException (); + } +#else [DllImport("libc")] public static extern int if_nametoindex(string ifname); @@ -90,6 +106,7 @@ namespace System.Net.NetworkInformation { [DllImport ("libc")] protected static extern void freeifaddrs (IntPtr ifap); +#endif } class MacOsNetworkInterfaceAPI : UnixNetworkInterfaceAPI @@ -290,8 +307,6 @@ namespace System.Net.NetworkInformation { } else if (sockaddr.sin_family == AF_PACKET) { sockaddr_ll sockaddrll = (sockaddr_ll) Marshal.PtrToStructure (addr.ifa_addr, typeof (sockaddr_ll)); if (((int)sockaddrll.sll_halen) > sockaddrll.sll_addr.Length){ - Console.Error.WriteLine ("Got a bad hardware address length for an AF_PACKET {0} {1}", - sockaddrll.sll_halen, sockaddrll.sll_addr.Length); next = addr.ifa_next; continue; } @@ -435,31 +450,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 l = new List (); - 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 (p); + l.Add (info); } + return l.ToArray (); } @@ -473,9 +491,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 +523,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 +532,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 @@ -615,6 +644,19 @@ namespace System.Net.NetworkInformation { string iface_operstate_path; string iface_flags_path; +#if MONODROID + [DllImport ("__Internal")] + static extern int _monodroid_get_android_api_level (); + + [DllImport ("__Internal")] + static extern bool _monodroid_get_network_interface_up_state (string ifname, ref bool is_up); + + [DllImport ("__Internal")] + static extern bool _monodroid_get_network_interface_supports_multicast (string ifname, ref bool supports_multicast); + + bool android_use_java_api; +#endif + internal string IfacePath { get { return iface_path; } } @@ -625,6 +667,9 @@ namespace System.Net.NetworkInformation { iface_path = "/sys/class/net/" + name + "/"; iface_operstate_path = iface_path + "operstate"; iface_flags_path = iface_path + "flags"; +#if MONODROID + android_use_java_api = _monodroid_get_android_api_level () >= 24; +#endif } public override IPInterfaceProperties GetIPProperties () @@ -643,6 +688,23 @@ namespace System.Net.NetworkInformation { public override OperationalStatus OperationalStatus { get { +#if MONODROID + if (android_use_java_api) { + // Starting from API 24 (Android 7 "Nougat") Android restricts access to many + // files in the /sys filesystem (see https://code.google.com/p/android/issues/detail?id=205565 + // for more information) and therefore we are forced to call into Java API in + // order to get the information. Alas, what we can obtain in this way is quite + // limited. In the case of OperationalStatus we can only determine whether the + // interface is up or down. There is a way to get more detailed information but + // it requires an instance of the Android Context class which is not available + // to us here. + bool is_up = false; + if (_monodroid_get_network_interface_up_state (Name, ref is_up)) + return is_up ? OperationalStatus.Up : OperationalStatus.Down; + else + return OperationalStatus.Unknown; + } +#endif if (!Directory.Exists (iface_path)) return OperationalStatus.Unknown; @@ -679,6 +741,17 @@ namespace System.Net.NetworkInformation { public override bool SupportsMulticast { get { +#if MONODROID + if (android_use_java_api) { + // Starting from API 24 (Android 7 "Nougat") Android restricts access to many + // files in the /sys filesystem (see https://code.google.com/p/android/issues/detail?id=205565 + // for more information) and therefore we are forced to call into Java API in + // order to get the information. + bool supports_multicast = false; + _monodroid_get_network_interface_supports_multicast (Name, ref supports_multicast); + return supports_multicast; + } +#endif if (!Directory.Exists (iface_path)) return false; @@ -747,11 +820,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); @@ -761,28 +834,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 l = new List (); - 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 (p); + l.Add (info); } return l.ToArray (); }