Проверьте, находится ли IP-адрес в локальной сети (за брандмауэрами и маршрутизаторами)
Я просканировал в сети около 5 часов и не нашел решения для своей проблемы:
Моя компания разрабатывает обучающую игру, и я пишу автоудатчик для нее, используя Monotorrent. Игра будет использоваться в школах, но из-за того, что большинство школ имеют очень слабые интернет-соединения, в сети должен быть только один компьютер, загружаемый с сервера httpseeder, а остальные должны пиявки с одного компьютера, загружаемого с httpseed.
Итак, я получаю множество IP-адресов от трекера и должен отфильтровывать только те, которые находятся в локальной сети.
Конечно, школы иногда довольно строгие с брандмауэрами, и в некоторых школах будет много маршрутизаторов и коммутаторов.
Я уже пробовал большинство решений, например,
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
);
}
}
Или аналогичные методы предоставляют только информацию о маршрутизаторе/коммутаторе/независимо.
Итак, вкратце, что я хочу сделать, это проверить, доступен ли данный IP-адрес через локальную сеть.
Я очень благодарен за любую помощь, потому что эта функция остается последней:)
Ответы
Ответ 1
Вы можете воспользоваться TTL. С TTL 1 пакет не сможет сделать это в Интернете:
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;
}
Однако помните, что он называется маской IPv4 по какой-либо причине - вы можете использовать его как один (так вот ваше алгоритмическое решение):
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;
}
Ответ 2
Как правило, любые IP-адреса, такие как 10.x.x.x(класс A) или 192.x.x.x(класс C), можно смело считать внутри частной локальной сети. IP-классификации
Ответ 3
Одна вещь, которую вы могли бы использовать, - это попытаться установить связь между клиентами с помощью многоадресной рассылки. Большинство брандмауэров и маршрутизаторов будут блокировать многоадресный трафик (и ISPs наиболее определенно), что означает, что вы не сможете присоединиться к группе многоадресной рассылки, если другой клиент не находится на LAN. Тупой коммутатор будет передавать трафик, слой 3-переключатель может блокировать его или может разрешить его в зависимости от конфигурации. В любом случае, если коммутатор уровня 3 блокирует его, вы, вероятно, все равно в разных подсетях, так что все остальные параметры также потерпят неудачу.
Одной технологией, которая приходит на ум, является SSDP (http://en.wikipedia.org/wiki/Simple_Service_Discovery_Protocol), который будет служить вашей цели довольно хорошо, я верю. Таким образом, вам действительно не нужно выяснять, находитесь ли вы в локальной сети или нет, просто выполните поиск другого node, который активно загружается, если вы не можете его найти, начните загрузку самостоятельно.
Поскольку SSDP является стандартом, используемым в uPnP, вы, вероятно, сможете найти достойные реализации, с которыми вы могли бы работать.