Cómo comprobar una caída de IP de entrada en un rango de IP específico

Si permitimos que los usuarios ingresen un par de rangos de IP, por ejemplo, 172.16.11.5 – 100, ¿cómo podría escribir una función para verificar si una IP (172.16.11.50) se encuentra dentro de los rangos?

¿Hay alguna biblioteca existente en .NET para aprovechar?

No hay nada integrado en el marco, pero no tomará mucho esfuerzo crear una clase IPAddressRange .

Debería comparar los rangos llamando a IPAddress.GetAddressBytes en la dirección inferior, la dirección superior y la dirección de comparación. Comenzando en el primer byte, verifique si la dirección de comparación está en el rango de la dirección superior / inferior.

Este método funciona para direcciones IPv4 e 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: El código anterior podría ampliarse para agregar métodos de fábrica estáticos públicos FromCidr(IPAddress address, int bits)

Es posible que desee considerar esta biblioteca con @jsakamoto, que le permite analizar el rango de la cadena de direcciones IP, como “192.168.0.0/24” y “192.168.0.0/255.255.255.0” y “192.168.0.0-192.168.0.255”. y puede conatins verificar. Esta biblioteca es compatible con IPv4 e IPv6.

https://github.com/jsakamoto/ipaddressrange

También se puede instalar a través de 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. 
 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 

Lo mejor es convertir estas direcciones a un número entero y luego realizar comparaciones.

Ejemplo de aquí: IP a Entero

Para convertir una dirección IP a entero, divídalo en cuatro octetos. Por ejemplo, la dirección IP que proporcionó se puede dividir en:

 First Octet: 217 Second Octet: 110 Third Octet: 18 Fourth Octet: 206 

Para calcular la dirección decimal de una cadena punteada, realice el siguiente cálculo.

  (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 

Teniendo en cuenta IPv6, también puede convertirlos en enteros (128 bits vs 32 bits IPv4). Eche un vistazo a esta pregunta: formatee IPv6 como un int en C # y almacénelo en SQL Server

La ruta más simple es hacer que el marco haga esto por usted. Use IPAddress.Parse para analizar la dirección, luego IPAddress.GetAddressBytes para obtener el “número” como byte[] .

Utilicé este código en codeproject antes, que puede ser útil para usted.

http://www.codeproject.com/KB/IP/ipnumbers.aspx

Tiene la posibilidad de agregar a IPList un rango de números de IP definidos por un número de De IP y un número de IP. El método divide el rango en rangos IP estándar y encuentra sus máscaras. Por lo tanto, el rango “10.0.0.5” a “10.0.0.20” se dividirá en los siguientes rangos y se agregará a la lista: 10.0.0.5, 10.0.0.20, 10.0.0.6/31, 10.0.0.16/30 y 10.0. 0.8 / 29 y tendrá la posibilidad de verificarlo.

Descargo de responsabilidad: La clase solo se prueba con conjuntos de datos simples, y la clase no tiene validación de los números de IP y las máscaras de IP proporcionadas. Esto se debe corregir antes de usarlo en entornos de producción.

publicando mi respuesta desde aquí

Hace un tiempo, tuve que encontrar la ubicación de una IP determinada. Obtuvimos el IP de la solicitud. Hay bases de datos gratuitas que nos dieron esta asignación. En IPv4, cuando decimos IP como “abcd”, es esencialmente a * (256^3) + b * (256^2) + c * (256) + d .

http://www.aboutmyip.com/AboutMyXApp/IP2Integer.jsp

así que cuando dices que quieres una dirección IP que empiece por “a”, estás buscando direcciones IP entre a * 256 ^ 3 y a * 256 ^ 3 + 256 * (256 ^ 2) (b = 256) + 256 * (256 ) (c = 256) + 256 (d = 256) (el límite inferior / superior puede variar un poco dependiendo de si desea incluir / excluir los límites).

Dicho esto, hay direcciones IP específicas reservadas para fines específicos (como 127.0.0.1 que es localhost, 0.0.0.0 no puede ser una IP, etc.).

Entonces tu consulta de linq sería

 from i in iList where i >= MIN && i <= MAX select i; 

donde iList es tu lista inicial MIN es tu valor mínimo para tu rango MAX es tu valor máximo para tu rango

¿Podría averiguar la máscara de subred de su rango de IP?

Si es así, entonces quizás puedas usar este método IsInSameSubnet .