wilcar tabla subredes subneteo rango direcciones direccion convertir clase calculo calcular calculadora binario c# ip cidr

c# - tabla - ¿Cómo ver si una dirección IP pertenece dentro de un rango de direcciones IP usando notación CIDR?



subredes ip (7)

Aquí tengo una referencia estática de los rangos que necesito verificar:

private static List<string> Ip_Range = new List<string>() { "12.144.86.0/23", "31.201.1.176/30", "46.36.198.101/32", "46.36.198.102/31", "46.36.198.104/31", "46.136.172.0/24", "63.65.11.0/24", "63.65.12.0/25", "63.65.12.128/26", "63.65.12.192/27", "63.65.12.224/28", "63.65.12.240/29", "63.65.12.248/30", "63.65.12.252/31", "63.65.12.254/32", "65.173.56.0/21", "67.23.241.179/32", "67.23.241.180/30", "67.23.241.184/29", "67.23.241.192/30", "67.23.241.196/31", "67.23.241.198/32", "72.32.164.56/29", "72.46.244.32/28", "74.91.16.48/29", "74.91.16.208/29", "74.91.20.48/28", "74.91.20.64/29", "74.112.134.120/29", "74.112.135.104/29", "74.205.37.16/29", "78.24.205.32/28", "98.129.27.88/29", "98.129.91.40/29", "166.114.0.0/16", "167.157.0.0/16", "174.143.165.80/29", "186.0.156.0/22", "186.2.0.0/17", "186.27.0.0/17", "190.0.248.0/21", "190.3.184.0/21" };

Aquí hay un pseudo código sobre cómo lo veo funcionando:

public static bool IpIsWithinRange(string ip) //Something like 127.0.0.1 or 184.56.26.35 { IPAddress incomingIp = IPAddress.Parse(ip); foreach (var subnet in Ip_Range) { IPAddress sub = IPAddress.Parse(subnet); ????? if (incomingIp "is in" sub) ? return true; } return false; }

¿Alguna sugerencia sobre cómo codificar esta funcionalidad?


Decidí responder mi propia pregunta para que la gente pueda beneficiarse. Si se puede mejorar, por favor hazlo!

¡ github.com/lduchosal/ipnetwork y funcionó fantásticamente! A continuación se muestra el código que utilicé:

using System.Net; public static class RedirectHelpers { public static bool IpIsWithinBoliviaRange(string ip) { IPAddress incomingIp = IPAddress.Parse(ip); foreach (var subnet in Bolivia_Ip_Range) { IPNetwork network = IPNetwork.Parse(subnet); if (IPNetwork.Contains(network, incomingIp)) return true; } return false; } private static List<string> Bolivia_Ip_Range = new List<string>() { "12.144.86.0/23", "31.201.1.176/30", "46.36.198.101/32", "46.36.198.102/31", "46.36.198.104/31", "46.136.172.0/24", "63.65.11.0/24", "63.65.12.0/25", "63.65.12.128/26", "63.65.12.192/27", "63.65.12.224/28", "63.65.12.240/29", "63.65.12.248/30", "63.65.12.252/31", "63.65.12.254/32", "65.173.56.0/21", "67.23.241.179/32", "67.23.241.180/30", "67.23.241.184/29", "67.23.241.192/30", "67.23.241.196/31", "67.23.241.198/32", "72.32.164.56/29", "72.46.244.32/28", "74.91.16.48/29", "74.91.16.208/29", "74.91.20.48/28", "74.91.20.64/29", "74.112.134.120/29", "74.112.135.104/29", "74.205.37.16/29", "78.24.205.32/28", "98.129.27.88/29", "98.129.91.40/29", "166.114.0.0/16", "167.157.0.0/16", "174.143.165.80/29", "186.0.156.0/22", "186.2.0.0/17", "186.27.0.0/17", "190.0.248.0/21", "190.3.184.0/21", "166.114.0.0/16", "167.157.0.0/16", "186.2.0.0/18", "190.11.64.0/20", "190.11.80.0/20", "190.103.64.0/20", "190.104.0.0/19", "190.107.32.0/20", "190.129.0.0/17", "190.181.0.0/18", "190.186.0.0/18", "190.186.64.0/18", "190.186.128.0/18", "200.7.160.0/20", "200.58.64.0/20", "200.58.80.0/20", "200.58.160.0/20", "200.58.176.0/20", "200.75.160.0/20", "200.85.128.0/20", "200.87.0.0/17", "200.87.128.0/17", "200.105.128.0/19", "200.105.160.0/19", "200.105.192.0/19", "200.112.192.0/20", "200.119.192.0/20", "200.119.208.0/20", "201.222.64.0/19", "201.222.96.0/19" }; }


Para empezar, debes usar eso:

IPNetwork ipnetwork = IPNetwork.Parse("192.168.168.100/29"); Console.WriteLine("CIDR: {0}", ipnetwork.Cidr);

Salida

CIDR: 29


Por suerte, la mayor parte del trabajo ya se ha hecho por usted (por lo que no tenemos que hacerlo). Echa un vistazo al proyecto de github.com/lduchosal/ipnetwork . Analizarás todas tus direcciones CIDR con IPNetwork.Parse . Luego, para ver si una dirección IPAddress específica está dentro del rango, use el método IPNetwork.Contains .

Me aburrí, así que aquí hay un método que puedes usar para probar si una dirección IP está dentro del rango o no:

private Dictionary<string, IPNetwork> netCache = null; public bool IsInRange(string ipAddress) { if (netCache == null) netCache = Ip_Range.ToDictionary((keyItem) => keyItem, (valueItem) => IPNetwork.Parse(valueItem)); return netCache.Values.Any(net => IPNetwork.Contains(net, IPAddress.Parse(ipAddress))); }

Esto depende de la lista Ip_Range de su pregunta, pero las traduce a instancias de IPNetwork (faltan los controles de seguridad para la brevedad).

Uso:

List<string> addrList = new List<string> { "12.144.86.1", "10.254.6.172" }; addrList.ForEach(addr => Console.WriteLine("{0}: {1}", addr, IsInRange(addr)));

Salida de prueba:

12.144.86.1: True 10.254.6.172: False

Por supuesto, todavía hay mucho que podría (y probablemente debería) hacer con eso, pero esto prueba el concepto.


Si entiende la notación CIDR, puede hacer fácilmente los cálculos en su método de análisis.

Básicamente, usted sabe que una dirección IPv4 tiene una longitud de 32 bits y que la notación CIDR significa que el número de bits detrás de la "/" son los bits de la dirección de red (es decir, los bits enmascarados), por lo tanto, los bits restantes representan el número de hosts en la subred

Del article wikipedia:

El número de direcciones de una subred definida por la máscara o el prefijo puede calcularse como tamaño de dirección 2 - tamaño de prefijo, en el que el tamaño de la dirección para IPv6 es 128 y 32 para IPv4. Por ejemplo, en IPv4, un tamaño de prefijo de / 29 da: 232-29 = 23 = 8 direcciones.

Así que podría (no, no voy a resolver los detalles por usted) convertir sus direcciones en binarias y hacer el Y binario con la máscara dada (también en forma binaria), entonces tiene la parte de la dirección de red de la dirección IP izquierda, que debería coincidir con cualquier dirección con la que esté verificando para ver si está en una subred en particular.


Si no desea / no puede agregar otra biblioteca (como la red IP) a su proyecto y solo necesita lidiar con los rangos CIDR de IPv4, aquí tiene una solución rápida para su problema

// true if ipAddress falls inside the CIDR range, example // bool result = IsInRange("10.50.30.7", "10.0.0.0/8"); private bool IsInRange(string ipAddress, string CIDRmask) { string[] parts = CIDRmask.Split(''/''); int IP_addr = BitConverter.ToInt32(IPAddress.Parse(parts[0]).GetAddressBytes(), 0); int CIDR_addr = BitConverter.ToInt32(IPAddress.Parse(ipAddress).GetAddressBytes(), 0); int CIDR_mask = IPAddress.HostToNetworkOrder(-1 << (32 - int.Parse(parts[1]))); return ((IP_addr & CIDR_mask) == (CIDR_addr & CIDR_mask)); }

lo anterior le permitirá verificar rápidamente si una dirección IPv4 determinada se encuentra dentro de un rango CIDR determinado; Observe que el código anterior es barebone, depende de usted verificar si una IP (cadena) y un rango CIDR dados son correctos antes de enviarlos a la función (solo puede usar el texto tripartito o lo que sea ...)


Uso el siguiente método para determinar si una dirección IP dada es pública o privada / interna:

private bool IsInternalIpAddress(string ipAddress) { // notes: http://whatismyipaddress.com/private-ip var internalIpRanges = Enumerable .Range(16, 31) .Select(i => "172.{0}.".FormatWith(i)) .Concat(new[] {"192.168.", "10.", "127."}) .ToArray(); return ipAddress.StartsWith(internalIpRanges); }


public static bool IpIsInRange(string subnet, string ip) { var splitSubnet = subnet.Split(''/''); var maskBits = 32 - int.Parse(splitSubnet[1]); if (maskBits == 32) { return true; } var subnetIp = BitConverter.ToInt32(IPAddress.Parse(splitSubnet[0]).GetAddressBytes().Reverse().ToArray(), 0) >> maskBits << maskBits; var clientIp = BitConverter.ToInt32(IPAddress.Parse(ip).GetAddressBytes().Reverse().ToArray(), 0) >> maskBits << maskBits; return subnetIp == clientIp; }