Как проверить, попадают ли входящие IP в определенный диапазон IP - PullRequest
63 голосов
/ 26 января 2010

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

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

Ответы [ 8 ]

115 голосов
/ 26 января 2010

Ничего не встроено в фреймворк, но для создания 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)

45 голосов
/ 13 декабря 2013

Возможно, вы захотите рассмотреть эту библиотеку с помощью @jsakamoto, которая позволяет анализировать диапазон строк IP-адресов, таких как «192.168.0.0/24» и «192.168.0.0/255.255.255.0» и «192.168.0.0-192.168. .0.255 ", и может проверить. Эта библиотека поддерживает как 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.
13 голосов
/ 24 июля 2012
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
8 голосов
/ 26 января 2010

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

Пример отсюда: 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[].

4 голосов
/ 26 января 2010

Я уже использовал этот код в 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-масок. это должно быть исправлено перед использованием в производственных средах.

3 голосов
/ 26 января 2010

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

Некоторое время назад мне нужно было найти местоположение данного 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-адреса от * 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 - ваше максимальное значение для вашего диапазона.

1 голос
/ 26 января 2010

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

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

0 голосов
/ 05 апреля 2019

Я хочу +1 от ответа BuddhiP выше, который рекомендует пакет 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
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...