В продолжение темы определения IP адреса по MAC адресу: возникла задача в Windows узнать IP адрес одного старого принтера, который подключен к сети 10.151.96.0/255.255.248.0, получает динамический адрес от DHCP сервера, но не регистрируется в DNS. Доступа к статистике DHCP сервера нет.
На самом деле, такая задача часто возникает и для других сетевых устройств, таких как IP видеокамеры, разные IP контроллеры.
Командный файл определения IP адреса позволяет просто и быстро узнать IP компьютера или того же принтера, но только в сетях с маской /24 (или 255.255.255.0).
10.151.99.12 00-40-af-7c-99-88 динамический
Идея нового скрипта та же, что и в командном файле для сетей /24 – скрипт пингует все IP адреса, возможные в данной сети, затем проверяет кэш arp.
Поэтому задача разделяется на две части:
- определение списка всех IP адресов данной сети,
- пинг с последующей проверкой кэша arp.
Определение списка IP адресов подсети
делаем через WMI на основе скрипта Считать сетевую конфигурацию. Скрипт определяет адрес подсети, число узлов и выводит все IP адреса, кроме адреса сети и широковещательного адреса. Первая редакция скрипта определяла узлы только для одного сетевого интерфейса, теперь добавлено определение узлов для нескольких интерфейсов (всех, кроме виртуальных).
function ip_to_array(ip) { var ip_p = ip.split("."); var a = new Array; for ( var i = 0; i < ip_p.length; ++i ) a.push( Number(ip_p[i]) ); return a; } function int_to_array(ip_int) { var a = new Array; for ( var i = 0; i < 4; ++i ) { var octet = ( ip_int >> ((3-i)*8) ) & 0xff; a.push( octet ); } return a; } var ipaddress; var ipsubnet; var computer = "."; var wmi = GetObject("winmgmts:\\\\" + computer + "\\root\\CIMV2"); var items = wmi.ExecQuery("SELECT * from Win32_NetworkAdapterConfiguration"); for ( var ci = new Enumerator(items); !ci.atEnd(); ci.moveNext() ) { var ipconfig = ci.item(); if ( !ipconfig.IPEnabled ) continue; if ( ipconfig.Caption.search(RegExp("virtual","i")) != -1 ) continue; // используем только один IP адрес с этого интерфейса ipaddress = ip_to_array(ipconfig.IPAddress(0)); ipsubnet = ip_to_array(ipconfig.IPSubnet(0)); var net_address = new Array; var host_max = 0; for ( var i = 0; i < 4; ++i ) { net_address.push( Number(ipaddress[i] & ipsubnet[i]) ); host_max += ( ( 255 - ipsubnet[i] ) << ( 8 * ( 3 - i ) ) ); } for ( var host = 1; host < host_max; ++host ) { var ip = int_to_array(host); for ( var i = 0; i < 4; ++i ) ip[i] += net_address[i]; WScript.Echo(ip[0] + "." + ip[1] + "." + ip[2] + "." + ip[3]); } //break; }
Например, команда cscript.exe //nologo list_hosts.js
выводит для сети 10.151.96.0/255.255.248.0 список из 2046 узлов:
10.151.96.1 10.151.96.2 ... 10.151.103.254
Опрос узлов сети по списку
делаем в командном файле (так проще). Скрипт list_hosts.js должен находиться в том же каталоге:
@echo off setlocal enabledelayedexpansion if "%~1" == "" echo Error: MAC no specified. && exit /b 2 if not exist "%~dp0\list_hosts.js" echo Error: list_hosts.js not found. && exit /b 3 set /a count=0 for /F %%i in ('cscript.exe //nologo "%~dp0list_hosts.js"') do ( start /b ping %%i -n 2 > nul set /a count=count+1 set /a check=count %% 100 if !check! == 0 ping -n 5 127.0.0.1 > nul & arp -a | find /i "%~1" && exit /b 0 ) exit /b 1
MAC адрес передаётся в виде аргумента:
ip_by_mac.cmd 00-40-af-7c-99-88
В этом командном файле проверка узлов выполняется «партиями» по 100 штук, т.е. командный файл запускает пинг по ста узлам, ждёт 5 секунд, проверяет кэш arp и, если запись найдена, выходит из цикла.
Такой подход несколько позволяет опрашивать большое количество узлов (например, сеть /21 может включать до 2046 узлов), не нагружая компьютер – по сравнению с предыдущим вариантом командного файла, в котором все процессы ping запускались одновременно.
10.151.99.12 00-40-af-7c-99-88 динамический
Скачать этот и другие скрипты.
Как проверить работу скрипта
Чтобы проверить работу скрипта, можно использовать любой узел с известным IP. Допустим, это 10.151.96.5
Определяем MAC адрес с помощью ping и arp:
C:\Windows\System32>ping 10.151.96.5 Pinging 10.151.96.5 with 32 bytes of data: Reply from 10.151.96.5: bytes=32 time<1ms TTL=255 Reply from 10.151.96.5: bytes=32 time<1ms TTL=255 Reply from 10.151.96.5: bytes=32 time=2ms TTL=255 Reply from 10.151.96.5: bytes=32 time<1ms TTL=255 Ping statistics for 10.151.96.5: Packets: Sent = 4, Received = 4, Lost = 0 (0% loss), Approximate round trip times in milli-seconds: Minimum = 0ms, Maximum = 2ms, Average = 0ms C:\Windows\System32>arp -a | find "10.151.96.5" 10.151.96.5 6c-9c-ed-ba-e7-d0 dynamic
Итак, тестовый узел имеет IP 10.151.96.5 и MAC 6c-9c-ed-ba-e7-d0.
Делаем паузу и проверяем, что запись об этом узле удалена из кэша arp:
C:\Windows\System32>arp -a | find "10.151.96.5" 10.151.96.5 6c-9c-ed-ba-e7-d0 dynamic
Запускаем командный файл:
ip_by_mac.cmd 6c-9c-ed-ba-e7-d0
Если узел будет найден, то вывод будет такой:
10.151.96.5 6c-9c-ed-ba-e7-d0 dynamic
Если вывод пустой, т.е. запись узла не найдена, то можно проверить список узлов, используемый скриптом:
cscript.exe //nologo list_hosts.js
и сравнить с расчётом на калькуляторе, например, http://netcalc.ru/:
Значение | x10 | x2 |
IP | 10.151.96.5 | 00001010.10010111.01100000.00000101 |
Mask | 255.255.248.000 | 11111111.11111111.11111000.00000000 |
Wildcard | 000.000.007.255 | 00000000.00000000.00000111.11111111 |
Адрес сети | 10.151.96.0 | 00001010.10010111.01100000.00000000 |
Первый хост | 10.151.96.1 | 00001010.10010111.01100000.00000001 |
Последний хост | 10.151.103.254 | 00001010.10010111.01100111.11111110 |
Широковещательный адрес | 10.151.103.255 | 00001010.10010111.01100111.11111111 |
Количество IP адресов | 2048 | |
Кол-во используемых IP адресов | 2046 |
Сравниваем вывод list_hosts.js и диапазон первый хост – последний хост из таблицы, они должны совпадать.
Узнать больше
Все скрипты с использованием WMI
Большое спасибо за скрипт. Нашел айпишник своего старого модема (нужно было снять с него настройки). Назначил на своей машине адрес 192.168.1.4, подсеть 255.255.0.0, подрубил модем, запустил скрипт и спустя некоторое время ура! адрес модема 192.168.0.201 (уже и не помню зачем такой назначал). Ось Windows 10 x64.
в cmd ввожу команду ip_by_mac_all.cmd 00-00-00-00-00-00
в итоге ничего не выдается.
в папки из которой запускается команда есть два файла с содержание указанным выше:
ip_by_mac_all.cmd
list_hosts.js
что я делаю не так?
А что это за MAC address такой из одних нулей? Нужно же вводить реальный MAC, для которого ищется IP адрес.
это пример. я вводил разные реальные маки. результата нет.
ip_by_mac.cmd у меня не работает. Хотя если просто в командной строке набрать arp -a, то в огромномсписке модно найти нужный МАК и ip-адрес.
Только что проверил, на Windows 7 x64 работает.
Возникает какая-то ошибка (какая?) или просто не находит? Как запускаете, какой Windows?
Обратите внимание, скрипт list_hosts.js используется командным файлом, соответственно, должен быть доступен.
Если командный файл ip_by_mac.cmd запускается не из текущего каталога, он может не найти скрипт, поэтому лучше вызывать так:
for /F %%i in ('cscript.exe //nologo "%~dp0\list_hosts.js"') do (
Текст поправлю с учётом этого.