Обнаружение устройств/компьютеров в моей сети

Я пытался написать образец программы для моего тестового проекта, чтобы узнать все устройства (например, 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.