how to determine whether an IP address in private?

后端 未结 5 1907
不知归路
不知归路 2020-12-09 02:30

So far I have this code:

NetworkInterface[] adapters = NetworkInterface.GetAllNetworkInterfaces();

foreach (NetworkInterface adapter in adapters)
{
  IPInte         


        
相关标签:
5条回答
  • 2020-12-09 03:20

    The best way to do this would be an extension method to the IP Address class

        /// <summary>
        /// An extension method to determine if an IP address is internal, as specified in RFC1918
        /// </summary>
        /// <param name="toTest">The IP address that will be tested</param>
        /// <returns>Returns true if the IP is internal, false if it is external</returns>
        public static bool IsInternal(this IPAddress toTest)
        {
            if (IPAddress.IsLoopback(toTest)) return true;
            else if (toTest.ToString() == "::1") return false;
    
            byte[] bytes = toTest.GetAddressBytes();
            switch( bytes[ 0 ] )
            {
                case 10:
                    return true;
                case 172:
                    return bytes[ 1 ] < 32 && bytes[ 1 ] >= 16;
                case 192:
                    return bytes[ 1 ] == 168;
                default:
                    return false;
            }
        }
    

    Then, one may call the method on an instance of the IP address class

        bool isIpInternal = ipAddressInformation.Address.IsInternal();
    
    0 讨论(0)
  • 2020-12-09 03:22

    The private address ranges are defined in RFC1918. They are:

    • 10.0.0.0 - 10.255.255.255 (10/8 prefix)
    • 172.16.0.0 - 172.31.255.255 (172.16/12 prefix)
    • 192.168.0.0 - 192.168.255.255 (192.168/16 prefix)

    You might also want to filter out link-local addresses (169.254/16) as defined in RFC3927.

    0 讨论(0)
  • A more detailed response is here:

    private bool _IsPrivate(string ipAddress)
    {
        int[] ipParts = ipAddress.Split(new String[] { "." }, StringSplitOptions.RemoveEmptyEntries)
                                 .Select(s => int.Parse(s)).ToArray();
        // in private ip range
        if (ipParts[0] == 10 ||
            (ipParts[0] == 192 && ipParts[1] == 168) ||
            (ipParts[0] == 172 && (ipParts[1] >= 16 && ipParts[1] <= 31))) {
            return true;
        }
    
        // IP Address is probably public.
        // This doesn't catch some VPN ranges like OpenVPN and Hamachi.
        return false;
    }
    
    0 讨论(0)
  • 2020-12-09 03:33

    Added IPv6 and localhost cases.

        /* An IP should be considered as internal when:
    
           ::1          -   IPv6  loopback
           10.0.0.0     -   10.255.255.255  (10/8 prefix)
           127.0.0.0    -   127.255.255.255  (127/8 prefix)
           172.16.0.0   -   172.31.255.255  (172.16/12 prefix)
           192.168.0.0  -   192.168.255.255 (192.168/16 prefix)
         */
        public bool IsInternal(string testIp)
        {
            if(testIp == "::1") return true;
    
            byte[] ip = IPAddress.Parse(testIp).GetAddressBytes();
            switch (ip[0])
            {
                case 10:
                case 127:
                    return true;
                case 172:
                    return ip[1] >= 16 && ip[1] < 32;
                case 192:
                    return ip[1] == 168;
                default:
                    return false;
            }
        }
    
    0 讨论(0)
  • 2020-12-09 03:35
    10.0.0.0        -   10.255.255.255  (10/8 prefix)
    172.16.0.0      -   172.31.255.255  (172.16/12 prefix)
    192.168.0.0     -   192.168.255.255 (192.168/16 prefix)
    

    Use the ranges defined in the RFC (as suggested by Anders); than use regular expression to detect/remove the private IP address from the list.

    Here is a sample RegEx to detect private IP addresses. (Not tested by me)

    (^127\.0\.0\.1)|
    (^10\.)|
    (^172\.1[6-9]\.)|(^172\.2[0-9]\.)|(^172\.3[0-1]\.)|
    (^192\.168\.)
    
    0 讨论(0)
提交回复
热议问题