Pregunta

Ok, es viernes por la tarde, y he tenido una semana larga, ¡agradecería algo de ayuda! Actualmente, tengo una lista de rangos de IP, de la siguiente manera:

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" });

Después de obtener la IP del cliente, si cae en algún lugar entre estos conjuntos de rangos, deben redirigirse a otro lugar.

Por ejemplo,

Si alguien visitara el sitio con la IP 192.168.0.1, se les permitiría el acceso. Si visitaron con 145.36.1.0, no se les permitiría el acceso porque se encuentra entre el primer rango en esa lista.

Podría dividir cada IP por el período y determinar dónde comienza a cambiar el rango, luego hacer una comparación, pero eso sería pesado en el servidor.

Sé que las IP son básicamente números decimales, pero no estoy realmente seguro de cómo funciona.

¿Alguien ha encontrado esto antes?

Saludos, Sean.

¿Fue útil?

Solución

Convierta cada dirección IP para numerar , y luego verifique si la dirección IP del usuario está entre esos números.

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;
    }
}

Otros consejos

Convertiría las direcciones IP a números de 32 bits y luego haría un simple > = From y < = Para verificar si está dentro del rango.

Por ejemplo, 192.168.1.1 - > 192 * 256 ^ 3 + 168 * 256 ^ 2 + 1 * 256 + 1.

Trabajando con sus valores, 145.36.0.0 - > 2435055616 y 145.36.0.0 - & Gt; 2435121151. Entonces 145.36.200.30 - & Gt; 2435106846, y cae en ese rango, por lo que es válido. Pero 145.35.255.255 - & Gt; 2435055615 no está en el rango (apenas), por lo que falla.

Escribiría mi clase de IPRange para que los captadores / establecedores conviertan internamente la cadena de IP en un número:

new IPRange { From = "145.36.0.0", To = "145.36.255.255" }

Establecería internamente:

int from = 145036000000;
int to = 145036255255;

Luego agregue un método .IsInRange (string ip) que convierta la IP entrante al nombre int form y haga una comparación simple.

public bool IsInRange(string ipStr)
{
    int ip = ConvertIPStringToInt(ipStr);
    return (from <= ip && ip <= to);
}

De esa manera, no tiene que dividir las IP en el rango por períodos cada vez que se verifica.

Solo por diversión (y cierta apariencia de integridad): la otra forma obvia de hacerlo es asegurarse de que siempre use 3 dígitos para cada segmento de la dirección IP cuando se almacena como una cadena, es decir, 145.36.0.0 debería ser 145.036. 000.000 - de esa manera las cadenas serían directamente comparables.

Y lo menos obvio sería tener una clase de dirección IP explícita y un rollo de su propio conjunto de lógica de comparación (supongo precipitadamente que ya no hay algo como esto enterrado en las profundidades del marco .NET. ..)

Leí sobre esto hace unos días.

Puede convertir sus rangos de IP y compararlos.

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

Aquí está la función IPStringToNumber que necesita:

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

Referencias:

http://www.sqlservercentral.com/scripts/Miscellaneous/31036/

http://www.sqlservercentral.com/Authors/Scripts/kgayda/ 17134 /

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top