c# - ejemplos - Verificar si la IP está en LAN(detrás de firewalls y enrutadores)
iptables forward ejemplos (3)
He estado rastreando en la web durante aproximadamente 5 horas y no he podido encontrar una solución para mi problema:
Mi compañía está desarrollando un juego educativo y estoy escribiendo un autoupdater usando Monotorrent. El juego se usará en las escuelas, pero debido a que la mayoría de las escuelas tienen conexiones de internet muy débiles, solo debe haber una computadora en la red que las descargue de un httpseeder, y las otras deben descargarse de la única computadora que está descargando de httpseed.
Así que obtengo un montón de direcciones IP del rastreador y necesito filtrar solo las que están en la LAN.
Por supuesto, las escuelas a veces son bastante estrictas con los firewalls y habrá un montón de enrutadores y conmutadores entre algunas computadoras en una escuela.
Ya he probado la mayoría de las soluciones, cosas como
NetworkInterface[] interfaces = NetworkInterface.GetAllNetworkInterfaces();
foreach (NetworkInterface iface in interfaces)
{
IPInterfaceProperties properties = iface.GetIPProperties();
foreach (UnicastIPAddressInformation address in properties.UnicastAddresses)
{
Console.WriteLine(
"{0} (Mask: {1})",
address.Address,
address.IPv4Mask
);
}
}
O técnicas similares solo entregan la información del enrutador / interruptor / lo que sea.
Entonces, en pocas palabras, lo que quiero hacer es verificar si una determinada IP es accesible a través de LAN.
Realmente agradecería cualquier ayuda porque esta característica es la última que queda :)
Podrías aprovechar TTL. Con un TTL de 1, el paquete no podrá llegar a Internet:
private static bool IsLanIP(IPAddress address)
{
var ping = new Ping();
var rep = ping.Send(address, 100, new byte[] { 1 }, new PingOptions()
{
DontFragment = true,
Ttl = 1
});
return rep.Status != IPStatus.TtlExpired && rep.Status != IPStatus.TimedOut && rep.Status != IPStatus.TimeExceeded;
}
Sin embargo, recuerde que se llama máscara IPv4 por una razón: puede usarlo como uno (así que aquí está su solución algorítmica):
private static bool IsLanIP(IPAddress address)
{
var interfaces = NetworkInterface.GetAllNetworkInterfaces();
foreach (var iface in interfaces)
{
var properties = iface.GetIPProperties();
foreach (var ifAddr in properties.UnicastAddresses)
{
if (ifAddr.IPv4Mask != null &&
ifAddr.Address.AddressFamily == AddressFamily.InterNetwork &&
CheckMask(ifAddr.Address, ifAddr.IPv4Mask, address))
return true;
}
}
return false;
}
private static bool CheckMask(IPAddress address, IPAddress mask, IPAddress target)
{
if (mask == null)
return false;
var ba = address.GetAddressBytes();
var bm = mask.GetAddressBytes();
var bb = target.GetAddressBytes();
if (ba.Length != bm.Length || bm.Length != bb.Length)
return false;
for (var i = 0; i < ba.Length; i++)
{
int m = bm[i];
int a = ba[i] & m;
int b = bb[i] & m;
if (a != b)
return false;
}
return true;
}
Por lo general, se puede suponer que cualquier IP como 10.xxx (Clase A) o 192.xxx (Clase C) se encuentra dentro de una red privada de área local. Clases de IP
Una cosa que posiblemente podría usar es tratar de comunicarse entre los clientes que usan multidifusión. La mayoría de los cortafuegos y enrutadores bloquearían el tráfico de multidifusión (y los ISP definitivamente), lo que significa que no se podría unir a un grupo de multidifusión si no hay otro cliente en la LAN. Un interruptor tonto pasaría en el tráfico, un interruptor de capa 3 podría bloquearlo, o podría permitirlo dependiendo de la configuración. De cualquier manera, si el switch de la capa 3 lo bloquea, probablemente se encuentre en diferentes subredes en total, de modo que todas las otras opciones también fallarían.
Una de las tecnologías que me viene a la mente es SSDP ( http://en.wikipedia.org/wiki/Simple_Service_Discovery_Protocol ) que creo que servirá para tu propósito. De esta forma, no necesita averiguar si está en una LAN o no, simplemente busque otro nodo que esté descargando activamente, si no puede encontrar uno, comience a descargarse usted mismo.
Como SSDP es un estándar utilizado en uPnP, probablemente pueda encontrar implementaciones decentes con las que pueda trabajar.