В продолжение темы определения 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/:

Значениеx10x2
IP10.151.96.500001010.10010111.01100000.00000101
Mask255.255.248.00011111111.11111111.11111000.00000000
Wildcard000.000.007.25500000000.00000000.00000111.11111111
Адрес сети10.151.96.000001010.10010111.01100000.00000000
Первый хост10.151.96.100001010.10010111.01100000.00000001
Последний хост10.151.103.25400001010.10010111.01100111.11111110
Широковещательный адрес10.151.103.25500001010.10010111.01100111.11111111
Количество IP адресов2048 
Кол-во используемых IP адресов2046 

Сравниваем вывод list_hosts.js и диапазон первый хостпоследний хост из таблицы, они должны совпадать.

Узнать больше

Все скрипты с использованием WMI

Наши соцсети

IP адрес по MAC адресу для любых сетей
Метки:         

6 мыслей о “IP адрес по MAC адресу для любых сетей

  • 15.03.2016 в 16:18
    Постоянная ссылка

    Большое спасибо за скрипт. Нашел айпишник своего старого модема (нужно было снять с него настройки). Назначил на своей машине адрес 192.168.1.4, подсеть 255.255.0.0, подрубил модем, запустил скрипт и спустя некоторое время ура! адрес модема 192.168.0.201 (уже и не помню зачем такой назначал). Ось Windows 10 x64.

    Ответ
  • 09.02.2015 в 12:00
    Постоянная ссылка

    в cmd ввожу команду ip_by_mac_all.cmd 00-00-00-00-00-00
    в итоге ничего не выдается.

    в папки из которой запускается команда есть два файла с содержание указанным выше:
    ip_by_mac_all.cmd
    list_hosts.js

    что я делаю не так?

    Ответ
  • 16.10.2014 в 08:13
    Постоянная ссылка

    ip_by_mac.cmd у меня не работает. Хотя если просто в командной строке набрать arp -a, то в огромномсписке модно найти нужный МАК и ip-адрес.

    Ответ
    • 16.10.2014 в 10:14
      Постоянная ссылка

      Только что проверил, на Windows 7 x64 работает.
      Возникает какая-то ошибка (какая?) или просто не находит? Как запускаете, какой Windows?
      Обратите внимание, скрипт list_hosts.js используется командным файлом, соответственно, должен быть доступен.
      Если командный файл ip_by_mac.cmd запускается не из текущего каталога, он может не найти скрипт, поэтому лучше вызывать так:
      for /F %%i in ('cscript.exe //nologo "%~dp0\list_hosts.js"') do (
      Текст поправлю с учётом этого.

      Ответ

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *