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



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



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

554   7  

7 ответов:

там ничего не построили в рамки, но это не займет много усилий, чтобы создать 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;
    }
}

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

вы можете рассмотреть эту библиотеку с помощью @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.
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

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

пример здесь: 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 в C# и сохранение его в SQL Server

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

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

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

у вас есть возможность добавить к IPList диапазон IP-номеров, определяемых a от IP и A до 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-масок, предоставляемых. Этот должно быть исправлено перед его использованием в производственных средах.

перепост моего ответа от здесь

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

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

поэтому, когда вы говорите, что хотите IP-адрес, начинающийся с "a", вы ищете IP-адреса между a * 256^ 3 и A * 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 ваш первоначальный список Мин Мин значение для диапазона максимум-это ваше максимальное значение для диапазон

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

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

Comments

    Ничего не найдено.