Подтвердить что ты не робот

Как определить, является ли IP-адрес приватным?

Пока у меня есть этот код:

NetworkInterface[] adapters = NetworkInterface.GetAllNetworkInterfaces();

foreach (NetworkInterface adapter in adapters)
{
  IPInterfaceProperties properties = adapter.GetIPProperties();

  foreach (IPAddressInformation uniCast in properties.UnicastAddresses)
  {

    // Ignore loop-back addresses & IPv6
    if (!IPAddress.IsLoopback(uniCast.Address) && 
      uniCast.Address.AddressFamily!= AddressFamily.InterNetworkV6)
        Addresses.Add(uniCast.Address);
  }
}

Как я могу отфильтровать частные IP-адреса? Точно так же я фильтрую IP-адреса loopback.

4b9b3361

Ответ 1

Более подробный ответ здесь:

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;
}

Ответ 2

Диапазоны частных адресов определены в RFC1918. Это:

  • 10.0.0.0 - 10.255.255.255 (префикс 10/8)
  • 172.16.0.0 - 172.31.255.255 (префикс 172.16/12)
  • 192.168.0.0 - 192.168.255.255 (префикс 192.168/16)

Вы также можете отфильтровать локальные локальные ссылки (169.254/16), как определено в RFC3927.

Ответ 3

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)

Используйте диапазоны, определенные в RFC (как было предложено Anders); чем использовать регулярное выражение для обнаружения/удаления частного IP-адреса из списка.

Вот пример RegEx для обнаружения частных IP-адресов. (Не проверено мной)

(^127\.0\.0\.1)|
(^10\.)|
(^172\.1[6-9]\.)|(^172\.2[0-9]\.)|(^172\.3[0-1]\.)|
(^192\.168\.)

Ответ 4

Лучше всего это будет метод расширения класса IP-адресов

    /// <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)
    {
        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;
        }
    }

Затем можно вызвать метод в экземпляре класса IP-адреса

    bool isIpInternal = ipAddressInformation.Address.IsInternal();

Ответ 5

Добавлены случаи IPv6 и localhost.

    /* 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;
        }
    }