using System.Globalization;
namespace System.Net.NetworkInformation {
- public abstract class NetworkInterface {
+ static class SystemNetworkInterface {
static readonly NetworkInterfaceFactory nif = NetworkInterfaceFactory.Create ();
- protected NetworkInterface ()
- {
- }
-
- public static NetworkInterface [] GetAllNetworkInterfaces ()
+ public static NetworkInterface [] GetNetworkInterfaces ()
{
try {
return nif.GetAllNetworkInterfaces ();
}
}
- [MonoTODO("Always returns true")]
- public static bool GetIsNetworkAvailable ()
+ public static bool InternalGetIsNetworkAvailable ()
{
+ // TODO:
return true;
}
-
- public static int LoopbackInterfaceIndex {
+
+ public static int InternalLoopbackInterfaceIndex {
get {
return nif.GetLoopbackInterfaceIndex ();
}
}
- public abstract IPInterfaceProperties GetIPProperties ();
- public abstract IPv4InterfaceStatistics GetIPv4Statistics ();
- public abstract PhysicalAddress GetPhysicalAddress ();
- public abstract bool Supports (NetworkInterfaceComponent networkInterfaceComponent);
+ public static int InternalIPv6LoopbackInterfaceIndex {
+ get {
+ throw new NotImplementedException ();
+ }
+ }
- public abstract string Description { get; }
- public abstract string Id { get; }
- public abstract bool IsReceiveOnly { get; }
- public abstract string Name { get; }
- public abstract NetworkInterfaceType NetworkInterfaceType { get; }
- public abstract OperationalStatus OperationalStatus { get; }
- public abstract long Speed { get; }
- public abstract bool SupportsMulticast { get; }
+ public static IPAddress GetNetMask (IPAddress address)
+ {
+ return nif.GetNetMask (address);
+ }
}
abstract class NetworkInterfaceFactory
class MacOsNetworkInterfaceAPI : UnixNetworkInterfaceAPI
{
+ const int AF_INET = 2;
+ const int AF_INET6 = 30;
+ const int AF_LINK = 18;
+
public override NetworkInterface [] GetAllNetworkInterfaces ()
{
- const int AF_INET = 2;
- const int AF_INET6 = 30;
- const int AF_LINK = 18;
-
var interfaces = new Dictionary <string, MacOsNetworkInterface> ();
IntPtr ifap;
if (getifaddrs (out ifap) != 0)
{
return if_nametoindex ("lo0");
}
+
+ public override IPAddress GetNetMask (IPAddress address)
+ {
+ IntPtr ifap;
+ if (getifaddrs (out ifap) != 0)
+ throw new SystemException ("getifaddrs() failed");
+
+ try {
+ IntPtr next = ifap;
+ while (next != IntPtr.Zero) {
+ MacOsStructs.ifaddrs addr = (MacOsStructs.ifaddrs) Marshal.PtrToStructure (next, typeof (MacOsStructs.ifaddrs));
+
+ if (addr.ifa_addr != IntPtr.Zero) {
+ // optain IPAddress
+ MacOsStructs.sockaddr sockaddr = (MacOsStructs.sockaddr) Marshal.PtrToStructure (addr.ifa_addr, typeof (MacOsStructs.sockaddr));
+
+ if (sockaddr.sa_family == AF_INET) {
+ MacOsStructs.sockaddr_in sockaddrin = (MacOsStructs.sockaddr_in) Marshal.PtrToStructure (addr.ifa_addr, typeof (MacOsStructs.sockaddr_in));
+ var saddress = new IPAddress (sockaddrin.sin_addr);
+ if (address.Equals (saddress))
+ return new IPAddress(((sockaddr_in)Marshal.PtrToStructure(addr.ifa_netmask, typeof(sockaddr_in))).sin_addr);
+ }
+ }
+ next = addr.ifa_next;
+ }
+ } finally {
+ freeifaddrs (ifap);
+ }
+
+ return null;
+ }
}
class LinuxNetworkInterfaceAPI : UnixNetworkInterfaceAPI
{
+ const int AF_INET = 2;
+ const int AF_INET6 = 10;
+ const int AF_PACKET = 17;
+
static void FreeInterfaceAddresses (IntPtr ifap)
{
#if MONODROID
public override NetworkInterface [] GetAllNetworkInterfaces ()
{
- const int AF_INET = 2;
- const int AF_INET6 = 10;
- const int AF_PACKET = 17;
var interfaces = new Dictionary <string, LinuxNetworkInterface> ();
IntPtr ifap;
{
return if_nametoindex ("lo");
}
+
+ public override IPAddress GetNetMask (IPAddress address)
+ {
+ foreach (ifaddrs networkInteface in GetNetworkInterfaces()) {
+ if (networkInteface.ifa_addr == IntPtr.Zero)
+ continue;
+
+ var sockaddr = (sockaddr_in)Marshal.PtrToStructure(networkInteface.ifa_addr, typeof(sockaddr_in));
+
+ if (sockaddr.sin_family != AF_INET)
+ continue;
+
+ if (!address.Equals(new IPAddress(sockaddr.sin_addr)))
+ continue;
+
+ var netmask = (sockaddr_in)Marshal.PtrToStructure(networkInteface.ifa_netmask, typeof(sockaddr_in));
+ return new IPAddress(netmask.sin_addr);
+ }
+
+ return null;
+ }
+
+ private static IEnumerable<ifaddrs> GetNetworkInterfaces()
+ {
+ IntPtr ifap = IntPtr.Zero;
+
+ try {
+ if (GetInterfaceAddresses(out ifap) != 0)
+ yield break;
+
+ var next = ifap;
+ while (next != IntPtr.Zero) {
+ var addr = (ifaddrs)Marshal.PtrToStructure(next, typeof(ifaddrs));
+ yield return addr;
+ next = addr.ifa_next;
+ }
+ } finally {
+ if (ifap != IntPtr.Zero)
+ FreeInterfaceAddresses(ifap);
+ }
+ }
}
+#if !MOBILE
class Win32NetworkInterfaceAPI : NetworkInterfaceFactory
{
- [DllImport ("iphlpapi.dll", SetLastError = true)]
+ private const string IPHLPAPI = "iphlpapi.dll";
+
+ [DllImport (IPHLPAPI, SetLastError = true)]
static extern int GetAdaptersAddresses (uint family, uint flags, IntPtr reserved, byte [] info, ref int size);
+ [DllImport (IPHLPAPI)]
+ static extern uint GetBestInterfaceEx (byte[] ipAddress, out int index);
+
unsafe static Win32_IP_ADAPTER_ADDRESSES [] GetAdaptersAddresses ()
{
byte [] bytes = null;
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 ()
+ {
+ return GetBestInterfaceForAddress (IPAddress.Loopback);
+ }
+
+ public override IPAddress GetNetMask (IPAddress address)
{
throw new NotImplementedException ();
}
}
+#endif
public abstract NetworkInterface [] GetAllNetworkInterfaces ();
public abstract int GetLoopbackInterfaceIndex ();
+ public abstract IPAddress GetNetMask (IPAddress address);
public static NetworkInterfaceFactory Create ()
{
-#if MONOTOUCH
+#if MONOTOUCH || XAMMAC
return new MacOsNetworkInterfaceAPI ();
#else
Version windowsVer51 = new Version (5, 1);
return new LinuxNetworkInterfaceAPI ();
}
+#if !MOBILE
if (Environment.OSVersion.Version >= windowsVer51)
return new Win32NetworkInterfaceAPI ();
+#endif
throw new NotImplementedException ();
#endif
}
}
+#if !MOBILE
class Win32NetworkInterface2 : NetworkInterface
{
[DllImport ("iphlpapi.dll", SetLastError = true)]
get { return !addr.NoMulticast; }
}
}
+#endif
}