#if !NETFX_CORE using System; using System.Collections.Generic; using System.Net; using System.Net.NetworkInformation; using System.Net.Sockets; namespace ServiceStack { /// /// Useful IPAddressExtensions from: /// http://blogs.msdn.com/knom/archive/2008/12/31/ip-address-calculations-with-c-subnetmasks-networks.aspx /// /// public static class IPAddressExtensions { public static IPAddress GetBroadcastAddress(this IPAddress address, IPAddress subnetMask) { var ipAdressBytes = address.GetAddressBytes(); var subnetMaskBytes = subnetMask.GetAddressBytes(); if (ipAdressBytes.Length != subnetMaskBytes.Length) throw new ArgumentException("Lengths of IP address and subnet mask do not match."); var broadcastAddress = new byte[ipAdressBytes.Length]; for (var i = 0; i < broadcastAddress.Length; i++) { broadcastAddress[i] = (byte)(ipAdressBytes[i] | (subnetMaskBytes[i] ^ 255)); } return new IPAddress(broadcastAddress); } public static IPAddress GetNetworkAddress(this IPAddress address, IPAddress subnetMask) { var ipAdressBytes = address.GetAddressBytes(); var subnetMaskBytes = subnetMask.GetAddressBytes(); return new IPAddress(GetNetworkAddressBytes(ipAdressBytes, subnetMaskBytes)); } public static byte[] GetNetworkAddressBytes(byte[] ipAdressBytes, byte[] subnetMaskBytes) { if (ipAdressBytes.Length != subnetMaskBytes.Length) throw new ArgumentException("Lengths of IP address and subnet mask do not match."); var broadcastAddress = new byte[ipAdressBytes.Length]; for (var i = 0; i < broadcastAddress.Length; i++) { broadcastAddress[i] = (byte)(ipAdressBytes[i] & (subnetMaskBytes[i])); } return broadcastAddress; } public static bool IsInSameIpv6Subnet(this IPAddress address2, IPAddress address) { if (address2.AddressFamily != AddressFamily.InterNetworkV6 || address.AddressFamily != AddressFamily.InterNetworkV6) { throw new ArgumentException("Both IPAddress must be IPV6 addresses"); } var address1Bytes = address.GetAddressBytes(); var address2Bytes = address2.GetAddressBytes(); return IsInSameIpv6Subnet(address1Bytes, address2Bytes); } public static bool IsInSameIpv6Subnet(this byte[] address1Bytes, byte[] address2Bytes) { if (address1Bytes.Length != address2Bytes.Length) throw new ArgumentException("Lengths of IP addresses do not match."); for (var i = 0; i < 8; i++) { if (address1Bytes[i] != address2Bytes[i]) { return false; } } return true; } public static bool IsInSameIpv4Subnet(this IPAddress address2, IPAddress address, IPAddress subnetMask) { if (address2.AddressFamily != AddressFamily.InterNetwork || address.AddressFamily != AddressFamily.InterNetwork) { throw new ArgumentException("Both IPAddress must be IPV4 addresses"); } var network1 = address.GetNetworkAddress(subnetMask); var network2 = address2.GetNetworkAddress(subnetMask); return network1.Equals(network2); } public static bool IsInSameIpv4Subnet(this byte[] address1Bytes, byte[] address2Bytes, byte[] subnetMaskBytes) { if (address1Bytes.Length != address2Bytes.Length) throw new ArgumentException("Lengths of IP addresses do not match."); var network1Bytes = GetNetworkAddressBytes(address1Bytes, subnetMaskBytes); var network2Bytes = GetNetworkAddressBytes(address2Bytes, subnetMaskBytes); return network1Bytes.AreEqual(network2Bytes); } /// /// Gets the ipv4 addresses from all Network Interfaces that have Subnet masks. /// /// public static Dictionary GetAllNetworkInterfaceIpv4Addresses() { var map = new Dictionary(); try { #if !SL5 foreach (var ni in NetworkInterface.GetAllNetworkInterfaces()) { foreach (var uipi in ni.GetIPProperties().UnicastAddresses) { if (uipi.Address.AddressFamily != AddressFamily.InterNetwork) continue; if (uipi.IPv4Mask == null) continue; //ignore 127.0.0.1 map[uipi.Address] = uipi.IPv4Mask; } } #endif } catch /*(NotImplementedException ex)*/ { //log.Warn("MONO does not support NetworkInterface.GetAllNetworkInterfaces(). Could not detect local ip subnets.", ex); } return map; } /// /// Gets the ipv6 addresses from all Network Interfaces. /// /// public static List GetAllNetworkInterfaceIpv6Addresses() { var list = new List(); try { #if !SL5 foreach (var ni in NetworkInterface.GetAllNetworkInterfaces()) { foreach (var uipi in ni.GetIPProperties().UnicastAddresses) { if (uipi.Address.AddressFamily != AddressFamily.InterNetworkV6) continue; list.Add(uipi.Address); } } #endif } catch /*(NotImplementedException ex)*/ { //log.Warn("MONO does not support NetworkInterface.GetAllNetworkInterfaces(). Could not detect local ip subnets.", ex); } return list; } } } #endif