Ограничение IP-адреса, если он находится между диапазонами IP-адресов
-
06-07-2019 - |
Вопрос
Хорошо, сегодня пятница, и у меня была долгая неделя, поэтому я был бы признателен за помощь!В настоящее время у меня есть список диапазонов IP-адресов следующим образом:
List<IPRange> ipRanges = new List<IPRange>();
ipRanges.Add(new IPRange { From = "145.36.0.0", To = "145.36.255.255" });
ipRanges.Add(new IPRange { From = "194.183.227.184", To = "194.183.227.191" });
ipRanges.Add(new IPRange { From = "193.131.192.0", To = "193.131.223.255" });
После получения IP-адреса клиента, если он попадает куда-либо между этими наборами диапазонов, их необходимо перенаправить в другое место.
Например,
Если кто-то посетил сайт с IP-адресом 192.168.0.1
, им был бы разрешен доступ.Если бы они посетили с 145.36.1.0
, им не будет разрешен доступ, потому что он находится между первым диапазоном в этом списке.
Я мог бы разделить каждый IP-адрес по периоду и определить, где диапазон начинает меняться, затем провести сравнение, но это было бы обременительно для сервера.
Я знаю, что IP-адреса - это в основном просто десятичные числа, но я не совсем уверен, как это работает.
Кто-нибудь сталкивался с этим раньше?
Твое здоровье, Шон.
Решение
Конвертировать каждый IP-адрес. > на номер , а затем проверьте, находится ли IP-адрес пользователя между этими номерами.
public double Dot2LongIP(string DottedIP)
{
int i;
string [] arrDec;
double num = 0;
if (DottedIP == "")
{
return 0;
}
else
{
arrDec = DottedIP.Split('.');
for(i = arrDec.Length - 1; i >= 0 ; i --)
{
num += ((int.Parse(arrDec[i])%256) * Math.Pow(256 ,(3 - i )));
}
return num;
}
}
Другие советы
Я бы преобразовал IP-адреса в 32-разрядные числа, а затем выполнил бы простые > = From и < = чтобы проверить, находится ли он в диапазоне.
Например, 192.168.1.1 - > 192 * 256 ^ 3 + 168 * 256 ^ 2 + 1 * 256 + 1.
Работа с вашими значениями, 145.36.0.0 - > 2435055616 и 145.36.0.0 - & Gt; 2435121151. Так 145.36.200.30 - & Gt; 2435106846, и попадает в этот диапазон, так что это действительно. Но 145.35.255.255 - & Gt; 2435055615 не находится в диапазоне (просто), поэтому он не работает.
Я бы написал свой класс IPRange, чтобы получатель / установщик внутренне преобразовали строку IP в число:
new IPRange { From = "145.36.0.0", To = "145.36.255.255" }
Будет внутренне установлен:
int from = 145036000000;
int to = 145036255255;
Затем добавьте метод .IsInRange (string ip), который преобразует входящий IP-адрес в форму имени int и выполняет простое сравнение.
public bool IsInRange(string ipStr)
{
int ip = ConvertIPStringToInt(ipStr);
return (from <= ip && ip <= to);
}
Таким образом, вам не нужно разделять IP-адреса в диапазоне по периодам при каждой проверке.
Просто для забавы (и некоторого подобия полноты) - другой очевидный способ сделать это - убедиться, что вы всегда используете 3 цифры для каждого сегмента IP-адреса при хранении в виде строки, т.е. 145.36.0.0 должно быть 145.036. 000.000 - таким образом, строки будут напрямую сопоставимы.
И менее очевидным было бы иметь явный класс IP-адресов и свернуть свой собственный набор логики сравнения (я опрометчиво предполагаю, что в глубине .NET-фреймворка уже нет ничего подобного. ..) р>
Я читал об этом несколько дней назад.
Вы можете преобразовать свои диапазоны IP-адресов и сравнить их.
IF exists (SELECT * from dbo.sysobjects
WHERE id = object_id(N'[dbo].[IsPrivateIP]')
AND OBJECTPROPERTY(id, N'IsScalarFunction') = 1)
DROP FUNCTION [dbo].[IsPrivateIP]
GO
CREATE FUNCTION dbo.IsPrivateIP( @vcIPAddress varchar(15))
/**************************************************************************
DESCRIPTION: Returns Numeric IP if not private, otherwise returns null
PARAMETERS:
@vcIPAddress - The string containing a valid IP
RETURNS: IP converted to bigint or null if a private IP
USAGE: SELECT dbo.IsPrivateIP( '207.158.26.10')
DEPENDANCIES: dbo.IPStringToNumber() function
AUTHOR: Karen Gayda
DATE: 06/11/2003
MODIFICATION HISTORY:
WHO DATE DESCRIPTION
--- ---------- ---------------------------------------------------
***************************************************************************/
RETURNS bigint
AS
BEGIN
DECLARE @biClassALo bigint ,
@biClassAHi bigint ,
@biClassBLo bigint ,
@biClassBHi bigint ,
@biClassCLo bigint ,
@biClassCHi bigint ,
@biIP bigint,
@bTemp int
SET @biClassALo = 167772160
SET @biClassAHi = 169549375
SET @biClassBLo = 2885681152
SET @biClassBHi = 2887778303
SET @biClassCLo = 3232235520
SET @biClassCHi = 3232301055
SET @biIP = dbo.IPStringToNumber(@vcIPAddress)
IF @biIP BETWEEN @biClassALo AND @biClassAHi OR @biIP BETWEEN @biClassBLo AND @biClassBHi
OR @biIP BETWEEN @biClassCLo AND @biClassCHi
SET @biIP = NULL
RETURN @biIP
END
GO
Вот функция IPStringToNumber, которая ему нужна:
IF exists (SELECT * from dbo.sysobjects
WHERE id = object_id(N'[dbo].[IPStringToNumber]')
AND OBJECTPROPERTY(id, N'IsScalarFunction') = 1)
DROP FUNCTION [dbo].[IPStringToNumber]
GO
CREATE FUNCTION dbo.IPStringToNumber( @vcIPAddress varchar(15))
/**************************************************************************
DESCRIPTION: Returns Numeric IP, otherwise returns null
PARAMETERS:
@vcIPAddress - The string containing a valid IP
RETURNS: IP converted to bigint or null if not a valid IP
USAGE: SELECT dbo.IPStringToNumber( '10.255.255.255')
AUTHOR: Karen Gayda
DATE: 06/11/2003
MODIFICATION HISTORY:
WHO DATE DESCRIPTION
--- ---------- ---------------------------------------------------
***************************************************************************/
RETURNS bigint
AS
BEGIN
DECLARE
@biOctetA bigint,
@biOctetB bigint,
@biOctetC bigint,
@biOctetD bigint,
@biIP bigint
DECLARE @tblArray TABLE
(
OctetID smallint, --Array index
Octet bigint --Array element contents
)
--split the IP string and insert each octet into a table row
INSERT INTO @tblArray
SELECT ElementID, Convert(bigint,Element) FROM dbo.Split(@vcIPAddress, '.')
--check that there are four octets and that they are within valid ranges
IF (SELECT COUNT(*) FROM @tblArray WHERE Octet BETWEEN 0 AND 255) = 4
BEGIN
SET @biOctetA = (SELECT (Octet * 256 * 256 * 256) FROM @tblArray WHERE OctetID = 1)
SET @biOctetB = (SELECT (Octet * 256 * 256 ) FROM @tblArray WHERE OctetID = 2)
SET @biOctetC = (SELECT (Octet * 256 ) FROM @tblArray WHERE OctetID = 3)
SET @biOctetD = (SELECT (Octet) FROM @tblArray WHERE OctetID = 4)
SET @biIP = @biOctetA + @biOctetB + @biOctetC + @biOctetD
END
RETURN(@biIP)
END
Ссылки:
http://www.sqlservercentral.com/scripts/Miscellaneous/31036/
http://www.sqlservercentral.com/Authors/Scripts/kgayda/17134/