Как проверить падение IP-адреса в определенном диапазоне IP-адресов

Если мы разрешим пользователям вводить несколько диапазонов ip, например 172,16,11,5-100, как я могу написать функцию для проверки того, попадает ли IP (172.16.11.50) в диапазоны?

Есть ли какая-либо существующая библиотека в .NET для использования?

Ответ 1

В инфраструктуру ничего не встроено, но создать класс IPAddressRange не потребуется.

Вы сравниваете диапазоны, вызывая IPAddress.GetAddressBytes на нижнем адресе, верхнем адресе и сравнительном адресе. Начиная с первого байта, проверьте, находится ли адрес сравнения в диапазоне верхнего/нижнего адреса.

Этот метод работает как для адресов IPv4, так и для IPv6.

public class IPAddressRange
{
    readonly AddressFamily addressFamily;
    readonly byte[] lowerBytes;
    readonly byte[] upperBytes;

    public IPAddressRange(IPAddress lowerInclusive, IPAddress upperInclusive)
    {
        // Assert that lower.AddressFamily == upper.AddressFamily

        this.addressFamily = lowerInclusive.AddressFamily;
        this.lowerBytes = lowerInclusive.GetAddressBytes();
        this.upperBytes = upperInclusive.GetAddressBytes();
    }

    public bool IsInRange(IPAddress address)
    {
        if (address.AddressFamily != addressFamily)
        {
            return false;
        }

        byte[] addressBytes = address.GetAddressBytes();

        bool lowerBoundary = true, upperBoundary = true;

        for (int i = 0; i < this.lowerBytes.Length && 
            (lowerBoundary || upperBoundary); i++)
        {
            if ((lowerBoundary && addressBytes[i] < lowerBytes[i]) ||
                (upperBoundary && addressBytes[i] > upperBytes[i]))
            {
                return false;
            }

            lowerBoundary &= (addressBytes[i] == lowerBytes[i]);
            upperBoundary &= (addressBytes[i] == upperBytes[i]);
        }

        return true;
    }
}

Примечание. Вышеприведенный код может быть расширен, чтобы добавить общедоступные статические методы factory FromCidr(IPAddress address, int bits)

Ответ 2

Возможно, вы захотите рассмотреть эту библиотеку с помощью @jsakamoto, которая позволяет анализировать диапазон строк IP-адресов, таких как "192.168.0.0/24" и "192.168.0.0/255.255.255.0" и "192.168.0.0-192.168.0.255"., и может conatins проверить. Эта библиотека поддерживает как IPv4, так и IPv6.

https://github.com/jsakamoto/ipaddressrange

Его также можно установить через NuGet:

http://www.nuget.org/packages/IPAddressRange/

using NetTools;
...
// rangeA.Begin is "192.168.0.0", and rangeA.End is "192.168.0.255".
var rangeA = IPAddressRange.Parse("192.168.0.0/255.255.255.0");
rangeA.Contains(IPAddress.Parse("192.168.0.34")); // is True.
rangeA.Contains(IPAddress.Parse("192.168.10.1")); // is False.
rangeA.ToCidrString(); // is 192.168.0.0/24

// rangeB.Begin is "192.168.0.10", and rangeB.End is "192.168.10.20".
var rangeB1 = IPAddressRange.Parse("192.168.0.10 - 192.168.10.20");
rangeB1.Contains(IPAddress.Parse("192.168.3.45")); // is True.
rangeB1.Contains(IPAddress.Parse("192.168.0.9")); // is False.

// Support shortcut range description. 
// ("192.168.10.10-20" means range of begin:192.168.10.10 to end:192.168.10.20.)
var rangeB2 = IPAddressRange.Parse("192.168.10.10-20");

// Support CIDR expression and IPv6.
var rangeC = IPAddressRange.Parse("fe80::/10"); 
rangeC.Contains(IPAddress.Parse("fe80::d503:4ee:3882:c586%3")); // is True.
rangeC.Contains(IPAddress.Parse("::1")); // is False.

Ответ 3

public static bool IsInRange(string startIpAddr, string endIpAddr, string address)
{
    long ipStart = BitConverter.ToInt32(IPAddress.Parse(startIpAddr).GetAddressBytes().Reverse().ToArray(), 0);

    long ipEnd = BitConverter.ToInt32(IPAddress.Parse(endIpAddr).GetAddressBytes().Reverse().ToArray(), 0);

    long ip = BitConverter.ToInt32(IPAddress.Parse(address).GetAddressBytes().Reverse().ToArray(), 0);

    return ip >= ipStart && ip <= ipEnd; //edited
}

Console.WriteLine(IsInRange("100.0.0.1", "110.0.0.255", "102.0.0.4"));//true

Ответ 4

Лучше всего преобразовать эти адреса в целое число, а затем выполнить сравнения.

Пример отсюда: IP для целого

Чтобы преобразовать IP-адрес в целое число, разделите его на четыре октета. Например, предоставленный ip-адрес можно разбить на:

First Octet:    217
Second Octet:   110
Third Octet:    18
Fourth Octet:   206

Чтобы вычислить десятичный адрес из точечной строки, выполните следующий расчет.

    (first octet * 256³) + (second octet * 256²) + (third octet * 256) + (fourth octet)
=   (first octet * 16777216) + (second octet * 65536) + (third octet * 256) + (fourth octet)
=   (217 * 16777216) + (110 * 65536) + (18 * 256) + (206)
=   3647869646

Учитывая IPv6, вы можете конвертировать их в целые (128 бит и 32-битные IPv4). Посмотрите на этот вопрос: Форматирование IPv6 как int на С# и сохранение его в SQL Server

Самый простой путь - получить чтобы сделать это для вас. использование IPAddress.Parse для анализа адреса, то IPAddress.GetAddressBytes, чтобы получить "число" как byte[].

Ответ 5

Я использовал этот код в codeproject прежде, что может быть полезно для вас.

http://www.codeproject.com/KB/IP/ipnumbers.aspx

У вас есть возможность добавить в IPList диапазон IP-номеров, определяемых номерами From IP и To IP. Метод разбивает диапазон на стандартные диапазоны IP-адресов и находит их маски. Таким образом, диапазон с "10.0.0.5" по "10.0.0.20" будет разбит на следующие диапазоны и добавлен в список: 10.0.0.5, 10.0.0.20, 10.0.0.6/31, 10.0.0.16/30 и 10.0. 0.8/29, и у вас будет возможность проверить это.

Отказ от ответственности: Класс тестируется только с простыми наборами данных, и в классе отсутствует проверка предоставленных номеров IP и масок IP. Это должно быть исправлено перед использованием в производственных средах.

Ответ 6

репост мой ответ отсюда

Некоторое время назад мне нужно было найти местоположение данного IP. Мы получили IP из запроса. Есть бесплатные базы данных, которые дали нам это отображение. В IPv4, когда мы говорим IP как "abcd", это по существу a * (256^3) + b * (256^2) + c * (256) + d.

http://www.aboutmyip.com/AboutMyXApp/IP2Integer.jsp

поэтому, когда вы говорите, что хотите, чтобы IP-адрес начинался с "а", вы ищете IP-адреса от * 256 ^ 3 до * 256 ^ 3 + 256 * (256 ^ 2) (b = 256) + 256 * (256 ) (c = 256) + 256 (d = 256) (нижний/верхний предел может немного отличаться в зависимости от того, хотите ли вы включить/исключить ограничения).

Тем не менее, существуют определенные IP-адреса, зарезервированные для определенных целей (например, 127.0.0.1, который является localhost, 0.0.0.0 не может быть IP-адресом и т.д.).

Так что ваш запрос linq будет

from i in iList where i >= MIN && i <= MAX select i;

где iList - ваш начальный список. MIN - ваше минимальное значение для вашего диапазона. MAX - ваше максимальное значение для вашего диапазона.

Ответ 7

Не могли бы вы определить маску подсети из вашего диапазона IP?

Если это так, возможно, вы можете использовать этот метод IsInSameSubnet.

Ответ 8

Я хочу +1 ответ BudhiP выше, который рекомендует пакет IPAddressRange от NuGet: https://www.nuget.org/packages/IPAddressRange/

Но поскольку форматирование кода сложно в комментарии, я просто добавлю здесь практический пример кода о том, как использовать IPAddressRange.

CheckIPWhitelist считывает параметр IPWhitelist и принимает список диапазонов IP, разделенных точкой с запятой (например, "192.168.10.10-20; 192.168.125.1-150; 192.168.123.1-150"), которые IPAddressRange может анализировать. Функция перебирает диапазоны и возвращает и возвращает true, если присутствует, false, если не найден.

Эта функция VB.NET и предполагает наличие некоторых зависимостей ASP.NET (таких как пространство имен System.Web.HttpRequest).

Imports NetTools ' ref. https://www.nuget.org/packages/IPAddressRange/

Function CheckIPWhitelist() As Boolean
    Dim match As Boolean = False
    Dim SourceIP As String = Request.UserHostAddress()

    ' Examples of valid IPWhitelist ranges 
    ' one range in longhand range format: "192.168.0.10 - 192.168.10.20"
    ' one range in shorthand range format: "192.168.10.10-20"
    ' multiple ranges separated by semicolons in shorthand range format: "192.168.10.10-20;192.168.125.1-150;192.168.123.1-150"
    Dim IPWhitelist As String = ConfigurationManager.AppSettings("IPWhitelist")

    Dim arrRanges As String() = IPWhitelist.Split(";")
    For i As Integer = 0 To arrRanges.Length - 1
        If arrRanges(i) IsNot Nothing Then
            Dim range As NetTools.IPAddressRange = IPAddressRange.Parse(arrRanges(i))
            If range.Contains(IPAddressRange.Parse(SourceIP)) = True Then
                match = True ' IP is in the whitelist, set a boolean
                Exit For
            End If
        End If
    Next
    Return match
End Function