Обнаружение устройств/компьютеров в моей сети
Я пытался написать образец программы для моего тестового проекта, чтобы узнать все устройства (например, Android или IOS) или другие компьютеры, подключенные к сети, к которой подключен мой компьютер.
Я могу видеть все подключенные устройства, когда я вхожу в консоль администрирования маршрутизатора, и мне нужен тот же список, используя мою программу.
Я попробовал пример кода, ниже которого я столкнулся с сообщением в https://gist.github.com/chrishulbert/895382, и нашел его интересным и попытался использовать его, но я не смог получить список. Я что-то пропустил в приведенном ниже коде, или это неправильный пример, который я имею в виду?. В этом отношении будет очень признательна любая помощь.
function listen(port) {
var server = dgram.createSocket("udp4");
server.on("message", function (msg, rinfo)
{
console.log("server got: " + msg + " from " + rinfo.address + ":" + rinfo.port);
});
server.bind(port);
}
function search() {
var message = new Buffer(
"M-SEARCH * HTTP/1.1\r\n" +
"HOST:239.255.255.250:1900\r\n" +
"MAN:\"ssdp:discover\"\r\n" +
"ST:ssdp:all\r\n" +
"MX:3\r\n" +
"\r\n"
);
var client = dgram.createSocket("udp4");
client.bind(0,"",function() {
console.log(client.address().port);
listen(client.address().port);
client.send(message, 0, message.length, 1900, "239.255.255.250",
function() {
// client.close();
});
}); // So that we get a port so we can listen before sending
}
search();
Ответы
Ответ 1
@Algi, наилучшим выбором для обнаружения устройства является использование протокола ICMP, требующего повышенных привилегий. Использование протокола UDP (который работает на уровне OSI 3 и 4, не подходит для обнаружения устройства, если не существует существующего протокола для обнаружения клиента и сервера, такого как те, которые используются в приложениях DNS, NetBIOS и DropBox).
Пожалуйста, не поймите неправильно, что обнаружение устройства может быть реализовано на этих протоколах более высокого уровня, но предположить, что устройство не существует в сети, потому что UDP/TCP-порт N не является открытым.
Как упоминалось @Josh3736, SSDP может быть реализован, но из-за его использования UPnP Я бы рекомендовал против этого по причинам, изложенным в этой статье.
@Illizian, я являюсь автором пакета node-libnmap и задавался вопросом, можете ли вы уточнить, когда скажете, что это "ненадежно". Какую версию вы использовали? Последняя версия стоит 0.1.10 и довольно стабильна.
Поскольку он взаимодействует с двоичным файлом nmap, возможно, на ваши результаты сканирования влияют параметры -min-rt-timeout, -max-rt-timeout и -initial-rt-timeout, которые реализуют реализацию "Idle scan" алгоритмов ".
Эти компоненты будут динамически устанавливать тайм-ауты на основе предыдущих значений зонда, которые при сканировании сильно фильтрованных (основанных на основах и основанных на периметре IDS и IPS-системах), то вы, несомненно, получите неожиданные результаты.
Как говорится, если вы испытываете проблемы за пределами этого диапазона, возможно, вы обнаружили ошибку? Если бы вы могли сообщить об этом в https://github.com/jas-/node-libnmap/issues?
На боковой ноте, использующей таблицу arp для обнаружения ближайших хостов, не будет предоставляться "все" доступные хосты в вашем сетевом сегменте. Только те, которые являются "болтливыми" в то время. Таблица arp постоянно выталкивает/выталкивает машины со стола.
Ответ 2
Я использую nmap в системе Unix, чтобы получить список устройств в сети. Существует библиотека NodeJS для взаимодействия с nmap (ссылка npm | github); поэтому вы можете получить список IP-адресов, используя следующий код:
require('node-libnmap').nmap('discover', function(err, report){
if (err) throw err
console.log(report)
});
и вы увидите следующий вывод:
{
adapter: 'eth0',
properties: {
address: '10.0.2.15',
netmask: '255.255.255.0',
family: 'IPv4',
mac: '52:54:00:12:34:56',
internal: false,
cidr: '10.0.2.0/24',
hosts: 256,
range: { start: '10.0.2.1', end: '10.0.2.254' }
},
neighbors: [ '10.0.2.2', '10.0.2.3', '10.0.2.15' ]
}
Надеюсь, что помогает:)
ОБНОВЛЕНИЕ: Я нашел nmap немного ненадежным и нашел альтернативу в node -arp library, следующий фрагмент выводит массив IP-адресов и MAC-адресов, обработанных из файла /proc/net/arp
:
var fs = require('fs');
fs.readFile('/proc/net/arp', function(err, data) {
if (!!err) return done(err, null);
var output = [];
var devices = data.toString().split('\n');
devices.splice(0,1);
for (i = 0; i < devices.length; i++) {
var cols = devices[i].replace(/ [ ]*/g, ' ').split(' ');
if ((cols.length > 3) && (cols[0].length !== 0) && (cols[3].length !== 0) && cols[3] !== '00:00:00:00:00:00') {
output.push({
ip: cols[0],
mac: cols[3]
});
}
}
console.log(output);
});
Ответ 3
Используемый вами код - это очень простая реализация SSDP. (Если вы хотите использовать SSDP, более полные модули.)
Проблема заключается в том, что другие устройства должны активно участвовать в процессе обнаружения SSDP. Это означает, что они должны слушать пакеты, которые вы отправляете, и отвечать им. Это не произойдет в большинстве конфигураций по умолчанию; таким образом, вы не получите никаких результатов.
Ваша страница администратора маршрутизатора может отображать список устройств, поскольку это DHCP-сервер. Ваш маршрутизатор отвечает за назначение IP-адресов каждому устройству в вашей сети, поэтому он знает о большинстве устройств. (Вы можете настроить устройство со статическим IP-адресом, и устройство, вероятно, не будет отображаться в списке маршрутизаторов.)
Простой подход - просто очистить страницу администратора маршрутизатора. Если вам повезет, ваш маршрутизатор предоставит эту информацию через API. В противном случае используйте request, чтобы получить страницу назначения адреса с панели администратора маршрутизатора и cheerio, чтобы проанализировать HTML.