Limitare un IP se è compreso in un intervallo IP
-
06-07-2019 - |
Domanda
Ok, è venerdì pomeriggio e ho trascorso una lunga settimana, quindi apprezzerei un po 'di aiuto! Attualmente, ho un elenco di intervalli IP, come segue:
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" });
Dopo aver ottenuto l'IP del client, se rientra in qualsiasi punto tra questi insiemi di intervalli, devono essere reindirizzati altrove.
Ad esempio,
Se qualcuno visitasse il sito con l'IP 192.168.0.1
, gli sarebbe consentito l'accesso.
Se visitassero con 145.36.1.0
, non avrebbero avuto accesso perché rientra nel primo intervallo in quell'elenco.
Potrei dividere ogni IP per il periodo e capire dove inizia a cambiare l'intervallo, quindi fare un confronto, ma sarebbe pesante sul server.
So che gli IP sono fondamentalmente solo numeri decimali, ma non sono sicuro di come funzioni.
Qualcuno l'ha mai visto prima?
Saluti, Sean.
Soluzione
Converti ogni indirizzo IP numerare , quindi verificare se l'indirizzo IP dell'utente è compreso tra tali numeri.
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;
}
}
Altri suggerimenti
Vorrei convertire gli indirizzi IP in numeri a 32 bit e quindi fare un semplice > = Da e < = Per verificare se è compreso nell'intervallo.
Ad esempio, 192.168.1.1 - > 192 * 256 ^ 3 + 168 * 256 ^ 2 + 1 * 256 + 1.
Lavorando con i tuoi valori, 145.36.0.0 - > 2435055616 e 145.36.0.0 - & Gt; 2435121151. Quindi 145.36.200.30 - & Gt; 2435106846 e rientra in tale intervallo, quindi è valido. Ma 145.35.255.255 - & Gt; 2435055615 non è nell'intervallo (appena) e quindi fallisce.
Scriverei la mia classe IPRange in modo che i getter / setter convertano internamente la stringa IP in un numero:
new IPRange { From = "145.36.0.0", To = "145.36.255.255" }
Impostarebbe internamente:
int from = 145036000000;
int to = 145036255255;
Quindi aggiungi un metodo .IsInRange (string ip) che converte l'IP in entrata nel nome int form e fa un semplice confronto.
public bool IsInRange(string ipStr)
{
int ip = ConvertIPStringToInt(ipStr);
return (from <= ip && ip <= to);
}
In questo modo non è necessario dividere gli IP nell'intervallo per periodi ogni volta che viene controllato.
Solo per divertimento (e una certa parvenza di completezza) - l'altro modo ovvio per farlo è quello di assicurarti di usare sempre 3 cifre per ogni segmento dell'indirizzo IP quando memorizzato come stringa cioè 145.36.0.0 dovrebbe essere 145.036. 000.000 - in questo modo le stringhe sarebbero direttamente comparabili.
E il meno ovvio sarebbe avere una classe di indirizzo IP esplicita e un roll-set il proprio set di logica di confronto (sto assumendo in modo affrettato che non c'è già qualcosa di simile seppellito nelle profondità del framework .NET. ..)
Ne ho letto alcuni giorni fa.
Puoi convertire e confrontare i tuoi intervalli 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
Ecco la funzione IPStringToNumber di cui ha bisogno:
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
References:
http://www.sqlservercentral.com/scripts/Miscellaneous/31036/
http://www.sqlservercentral.com/Authors/Scripts/kgayda/ 17134 /