Calculating all addresses within a subnet…for IPv6

前端 未结 4 1260
失恋的感觉
失恋的感觉 2021-01-02 17:26

I have seen plenty of great C# examples which demonstrate how to convert IPv4 addresses provided in CIDR notation (e.g. 192.168.0.1/25) into their relevant ranges (192.168.0

4条回答
  •  傲寒
    傲寒 (楼主)
    2021-01-02 18:08

    exNetworkLibrary is a great tool but if you can't use it in your project then you may just want to see this article:

    http://www.codeproject.com/Articles/112020/IP-Address-Extension

    It outlines how address masks are calculated for use in IPv4.

    Your question is related to IPv6 I see and Since .Net 4.5 there is a IPAddress.MapToIPv6 method.

    https://msdn.microsoft.com/en-us/library/system.net.ipaddress.maptoipv6(v=vs.110).aspx

    You can utilize that with the checks in the article to produce this code:

        private static IPAddress empty = IPAddress.Parse("0.0.0.0");
        private static IPAddress intranetMask1 = IPAddress.Parse("10.255.255.255");
        private static IPAddress intranetMask2 = IPAddress.Parse("172.16.0.0");
        private static IPAddress intranetMask3 = IPAddress.Parse("172.31.255.255");
        private static IPAddress intranetMask4 = IPAddress.Parse("192.168.255.255");
    
        /// 
        /// Retuns true if the ip address is one of the following
        /// IANA-reserved private IPv4 network ranges (from http://en.wikipedia.org/wiki/IP_address)
        ///  Start        End   
        ///  10.0.0.0       10.255.255.255  
        ///  172.16.0.0       172.31.255.255    
        ///  192.168.0.0   192.168.255.255 
        /// 
        /// 
        public static bool IsOnIntranet(this IPAddress ipAddress)
        {
            if (empty.Equals(ipAddress))
            {
                return false;
            }
    
            bool onIntranet = IPAddress.IsLoopback(ipAddress);
    
            if (false == onIntranet)
            {
                //Handle IPv6 by getting the IPv4 Mapped Address. 
                if (ipAddress.AddressFamily == AddressFamily.InterNetworkV6)
                {
                    onIntranet = ipAddress.Equals(ipAddress.And(intranetMask1.MapToIPv6())); //10.255.255.255
                    onIntranet = onIntranet || ipAddress.Equals(ipAddress.And(intranetMask4.MapToIPv6())); ////192.168.255.255
    
                    onIntranet = onIntranet || (intranetMask2.Equals(ipAddress.And(intranetMask2.MapToIPv6()))
                      && ipAddress.Equals(ipAddress.And(intranetMask3.MapToIPv6())));
                }
                else
                {
                    onIntranet = ipAddress.Equals(ipAddress.And(intranetMask1)); //10.255.255.255
                    onIntranet = onIntranet || ipAddress.Equals(ipAddress.And(intranetMask4)); ////192.168.255.255
    
                    onIntranet = onIntranet || (intranetMask2.Equals(ipAddress.And(intranetMask2))
                      && ipAddress.Equals(ipAddress.And(intranetMask3)));
                }
    
    
            }
    
            return onIntranet;
        }
    
    private static void CheckIPVersion(IPAddress ipAddress, IPAddress mask, out byte[] addressBytes, out byte[] maskBytes)
        {
            if (mask == null)
            {
                throw new ArgumentException();
            }
    
            addressBytes = ipAddress.GetAddressBytes();
            maskBytes = mask.GetAddressBytes();
    
            if (addressBytes.Length != maskBytes.Length)
            {
                throw new ArgumentException("The address and mask don't use the same IP standard");
            }
        }
    
        public static IPAddress And(this IPAddress ipAddress, IPAddress mask)
        {
            byte[] addressBytes;
            byte[] maskBytes;
            CheckIPVersion(ipAddress, mask, out addressBytes, out maskBytes);
    
            byte[] resultBytes = new byte[addressBytes.Length];
            for (int i = 0, e = addressBytes.Length; i < e; ++i)
            {
                resultBytes[i] = (byte)(addressBytes[i] & maskBytes[i]);
            }
    
            return new IPAddress(resultBytes);
        }
    

提交回复
热议问题