<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
	<channel>
		<title><![CDATA[Серый форум &mdash; CMD/BAT: Асинхронный ICMP-сканер подсети]]></title>
		<link>https://forum.script-coding.com/viewtopic.php?id=7310</link>
		<atom:link href="https://forum.script-coding.com/extern.php?action=feed&amp;tid=7310&amp;type=rss" rel="self" type="application/rss+xml" />
		<description><![CDATA[Недавние сообщения в теме «CMD/BAT: Асинхронный ICMP-сканер подсети».]]></description>
		<lastBuildDate>Fri, 29 Jun 2012 11:01:55 +0000</lastBuildDate>
		<generator>PunBB</generator>
		<item>
			<title><![CDATA[Re: CMD/BAT: Асинхронный ICMP-сканер подсети]]></title>
			<link>https://forum.script-coding.com/viewtopic.php?pid=61279#p61279</link>
			<description><![CDATA[<p><strong>vors</strong>, посмотрите на такой: <a href="http://forum.script-coding.com/viewtopic.php?id=3783">VBScript: асинхронная обработка множественных запросов WMI</a> вариант.</p>]]></description>
			<author><![CDATA[null@example.com (alexii)]]></author>
			<pubDate>Fri, 29 Jun 2012 11:01:55 +0000</pubDate>
			<guid>https://forum.script-coding.com/viewtopic.php?pid=61279#p61279</guid>
		</item>
		<item>
			<title><![CDATA[Re: CMD/BAT: Асинхронный ICMP-сканер подсети]]></title>
			<link>https://forum.script-coding.com/viewtopic.php?pid=61278#p61278</link>
			<description><![CDATA[<p>netsh inter ip show address<br />netsh inter ipv6 show address</p>]]></description>
			<author><![CDATA[null@example.com (smaharbA)]]></author>
			<pubDate>Fri, 29 Jun 2012 10:43:42 +0000</pubDate>
			<guid>https://forum.script-coding.com/viewtopic.php?pid=61278#p61278</guid>
		</item>
		<item>
			<title><![CDATA[Re: CMD/BAT: Асинхронный ICMP-сканер подсети]]></title>
			<link>https://forum.script-coding.com/viewtopic.php?pid=61277#p61277</link>
			<description><![CDATA[<p>Спасибо, <strong>smaharbA</strong>. Но я не об этом. <img src="//forum.script-coding.com/img/smilies/smile.png" width="15" height="15" /></p><p>Собственно, вопроса никакого не было. Я просто поделился. И предупредил о возможном эффекте.</p><p>Речь была о подсказке по использованию (usage). Там для примера подставляется локальный ip/маска, который вытягивается из вывода ipconfig.<br />Проблемы никакой нет - можно просто еще один фильтр find /V наложить:</p><div class="codebox"><pre><code> for /F &quot;tokens=1* delims=:&quot; %%i in (&#039;ipconfig^|find &quot;IP&quot;^|find /V &quot;IPv6&quot;^|find &quot;:&quot;&#039;) do set ip=%%j</code></pre></div>]]></description>
			<author><![CDATA[null@example.com (vors)]]></author>
			<pubDate>Fri, 29 Jun 2012 10:25:20 +0000</pubDate>
			<guid>https://forum.script-coding.com/viewtopic.php?pid=61277#p61277</guid>
		</item>
		<item>
			<title><![CDATA[Re: CMD/BAT: Асинхронный ICMP-сканер подсети]]></title>
			<link>https://forum.script-coding.com/viewtopic.php?pid=61275#p61275</link>
			<description><![CDATA[<p>ping -4</p>]]></description>
			<author><![CDATA[null@example.com (smaharbA)]]></author>
			<pubDate>Fri, 29 Jun 2012 09:55:30 +0000</pubDate>
			<guid>https://forum.script-coding.com/viewtopic.php?pid=61275#p61275</guid>
		</item>
		<item>
			<title><![CDATA[Re: CMD/BAT: Асинхронный ICMP-сканер подсети]]></title>
			<link>https://forum.script-coding.com/viewtopic.php?pid=61274#p61274</link>
			<description><![CDATA[<p>Вышеприведенный скрипт - довольно топорный. В нем сканируется только подсеть C-класса и время работы составляет свыше 20 сек., т.к. время ожидания завершения пингов подобрано опытным путем и хардкодно установлено в 20 сек.</p><p>Между тем, сканировать подсеть класса C нужно не всегда - иногда бывает побольше, а иногда и значительно меньше.</p><p>Таким образом, нужно добавить в скрипт еще один параметр - маску подсети. А также научиться определять время завершения всех порожденных пингов.</p><p>Для решения второго вопроса будем в цикле пытаться переименовать файлы сами в себя до тех пор, пока не удастся сделать это для каждого из них.<br />А для работы с масками (в CIDR-формате) - задействуем богатый механизм двоичной арифметики в команде set /A. Ну и добавим немного плюшек, типа контроля введенных значений и подсказки с ip и маской данного хоста:</p><div class="codebox"><pre><code>::
:: Simple network scanner
:: 2011 (c) vors
::
@echo off
setlocal ENABLEDELAYEDEXPANSION
:: Refine input to comply with the pattern of ip/cidr-mask
if &quot;%1&quot;==&quot;&quot; goto usage
echo %1 | findstr &quot;[0-9]*\.[0-9]*\.[0-9]*\.[0-9]*/[0-9]*&quot; &gt;nul || goto usage

set input=%1
set ip=%input:~0,-3%
set cidr=%input:*/=%
if %cidr% gtr 30 set cidr=30
if %cidr% lss 16 echo Scanning such much half of teh Intarnet no possible^^! You crazy. &amp; exit /b
::echo %ip%

:: Parse given ip-address to extract network and host parts
for /F &quot;tokens=1,2,3* delims=.&quot; %%i in (&#039;echo %ip%&#039;) do (
    set /A host=&quot;%%k &lt;&lt; 8 | %%l&quot;
    set /A host4=&quot;host &amp; 0xFF&quot;
    set /A host3=&quot;host &gt;&gt; 8&quot;
    set netw=%%i.%%j
)
::echo network = %netw%
::echo %host% = %host3%.%host4%

:: Determine range to scan
set /A range=&quot;(1 &lt;&lt; 32-cidr)-2&quot;
::echo range= %range%
set /A base=&quot;((0xffff &lt;&lt; 32-cidr) &amp; host)+1&quot;
set /A base4=&quot;base &amp; 0xFF&quot;
set /A base3=&quot;base &gt;&gt; 8&quot;
::echo %base% = %base3%.%base4%
set /A ceil=&quot;base+range-1&quot;
set /A ceil4=&quot;ceil &amp; 0xFF&quot;
set /A ceil3=&quot;ceil &gt;&gt; 8&quot;
::echo %ceil% = %ceil3%.%ceil4%
echo * Range: %netw%.%base3%.%base4% - %netw%.%ceil3%.%ceil4% ^(%range% hosts^)
echo.
:: Задаем сигнальные строки (отличаются в зависимости от локали)
echo | find &quot;is&quot; &gt;nul || goto set_ru
:set_en
set STR1=&quot;Reply [&quot;
set STR2=&quot;: bytes&quot;
set TKNS=2,3
set STR3=Scattering pings. Don&#039;t be scared, they all will stop in a moment...
set STR4=Waiting for pings to stop (approx. 10-20 sec)...
set STR5=A bit of make-up...
set STR6=All done^^!
goto set_end
:set_ru
set STR1=&quot;Ответ [&quot;
set STR2=&quot;: число&quot;
set TKNS=4,5
set STR3=Залп из пингов. Не пугайтесь, в считанные секунды всё утихнет...
set STR4=Ожидание завершения всех пингов (~10-20 сек)...
set STR5=Маленькое причесывание результата...
set STR6=Готово^^!
:set_end

:: Создаем временную директорию
pushd %TEMP%
if exist %netw% rd /S /Q %netw%
md %netw%
cd %netw%

set IMAX=128
:: Полный пинг подсети (асинхронно)
echo * %time% %STR3%
for /L %%i in (%base%,1,%ceil%) do (
    set /A i0=&quot;%%i - IMAX&quot;
    if !i0! geq %base% call :wait !i0!
    set /A i4=&quot;%%i &amp; 0xFF&quot;
    set /A i3=&quot;%%i &gt;&gt; 8&quot;
    start /b cmd /c ping -a -n 1 %netw%.!i3!.!i4! ^| findstr %STR1% &gt; %netw%.!i3!.!i4!
)

:: Ожидание завершения всех пингов
echo * %time% %STR4%
:loop
ping -n 2 127.0.0.1 &gt;nul
if not exist %netw%.%ceil3%.%ceil4% goto loop
for %%i in (*) do ren %%i %%i 2&gt;nul || goto loop

:: Зачистка безответных пингов
echo * %time% %STR5%
for %%i in (*) do find %STR2% &lt;%%i &gt;nul || del %%i

:: Причесывание оставшихся живых
for /f &quot;tokens=%TKNS% delims=[] &quot; %%i in (&#039;for %%h in ^(*^) do @type %%h ^|find &quot;[&quot;&#039;) do ren %%j &quot;%%j %%i&quot;
echo * %time% %STR6%
echo.
:: Вывод результата
:: dir /b
:: Штатной числовой сортировки нет, поэтому мутим ея своими силами
for /L %%i in (%base3%,1,%ceil3%) do for /L %%j in (%base4%,1,%ceil4%) do if exist %netw%.%%i.%%j (dir /b %netw%.%%i.%%j) else if exist &quot;%netw%.%%i.%%j *&quot; (dir /b &quot;%netw%.%%i.%%j *&quot;)

:: Убираем за собой
cd ..
rd /S /Q %netw%
popd
endlocal
exit /b

:: Functions &amp; procedures
:usage
echo Usage: %~nx0 ^&lt;ip-address^&gt;/^&lt;cidr-mask^&gt;
echo.
echo Scans a network (calculated from given ip and mask) with pings to
echo determine which hosts are really alive hence which IPs are vacant.
echo.
call :myip
echo Example: %~nx0 %ip%/%cidr%
endlocal
exit /b

:myip
for /F &quot;tokens=1* delims=:&quot; %%i in (&#039;ipconfig^|find &quot;IP&quot;^|find &quot;:&quot;&#039;) do set ip=%%j
for /F &quot;tokens=1* delims=:&quot; %%i in (&#039;ipconfig^|find &quot;255&quot;&#039;) do set mask=%%j
for /F &quot;tokens=1,2,3* delims=.&quot; %%i in (&quot;%mask%&quot;) do set /A hexmask=&quot;%%i&lt;&lt;24|%%j&lt;&lt;16|%%k&lt;&lt;8|%%l&quot;
for /L %%i in (0,1,31) do if !hexmask!==0 (set cidr=%%i &amp; goto done) else set /A hexmask=&quot;hexmask&lt;&lt;1&quot;
:done
exit /b

:wait
set /A p4=&quot;%1 &amp; 0xFF&quot;
set /A p3=&quot;%1 &gt;&gt; 8&quot;
:wait_loop
ren %netw%.%p3%.%p4% %netw%.%p3%.%p4% 2&gt;nul || goto wait_loop
goto :EOF</code></pre></div><p>При сканировании подсети большого размера (с маской меньше /24) даже на мощных машинах могли возникать проблемы с ресурсами, поэтому был введен параметр IMAX - максимальное число одновременно запущенных пингов.</p><p>Есть косячок с подсказкой на машинах с включенным IPv6 - может подхватиться именно IPv6-адрес.</p>]]></description>
			<author><![CDATA[null@example.com (vors)]]></author>
			<pubDate>Fri, 29 Jun 2012 09:43:29 +0000</pubDate>
			<guid>https://forum.script-coding.com/viewtopic.php?pid=61274#p61274</guid>
		</item>
		<item>
			<title><![CDATA[CMD/BAT: Асинхронный ICMP-сканер подсети]]></title>
			<link>https://forum.script-coding.com/viewtopic.php?pid=61272#p61272</link>
			<description><![CDATA[<p>Довольно часто возникает необходимость выяснить &quot;демографию&quot; того или иного участка корпоративной сети - какие ip заняты, какие хосты живы, какие у хостов имена и т.п. Зачастую эти участки являются обособленными подсетями, не имеющими непосредственного контакта ни с интернетом, ни с собственно сетью предприятия (например, биржевые терминалы трейдеров в банке). А если еще ИБ запрещает посторонний софт...<br />В таких случаях, когда под рукой только консоль cmd и собственные ручки, на помощь приходит простенький цикл, который, к слову, здесь уже не раз обсуждался:</p><div class="codebox"><pre><code> for /l %i in (1,1,254) do @ping -a -n 1 192.168.100.%i</code></pre></div><p>Однако, есть у этого решения досадные минусы: долго работает и выводит в не слишком удобном для просмотра и анализа виде.</p><p>Как бы сделать батник многопоточным, да еще чтоб данные сверстались в нужном формате?</p><p>Легко! Пинги запускаем асинхронно с помощью команды start. Результат каждого пинга перенаправляем в файл с именем пингуемого ip-адреса. Дожидаемся завершения всех пингов, считываем результирующие файлы, выкидываем из них всё лишнее и выводим:</p><div class="codebox"><pre><code>@echo off
:: Запуск:
:: scan.cmd &lt;subnet&gt;
::
:: Параметры:
:: &lt;subnet&gt; - три первых октета ip-адреса (идентификатор подсети)
::

if &quot;%1&quot;==&quot;&quot; goto usage

:: Задаем сигнальные строки (отличаются в зависимости от локали)
echo | find &quot;is&quot; &gt;nul || goto set_ru
:set_en
set STR1=&quot;Reply [&quot;
set STR2=&quot;: bytes&quot;
set TKNS=2,3
goto set_end
:set_ru
set STR1=&quot;Ответ [&quot;
set STR2=&quot;: число&quot;
set TKNS=4,5
:set_end

:: Создаем временную директорию
pushd %APPDATA%
md %1
cd %1

:: Полный пинг подсети (асинхронно)
echo * Залп из пингов. Не пугайтесь, в считанные секунды всё утихнет...
for /l %%i in (1,1,254) do start /b cmd /c ping -a -n 1 %1.%%i ^| findstr %STR1% &gt; %1.%%i

:: Ожидание завершения всех пингов
echo * Ожидание завершения всех пингов (20 сек)...
ping -n 20 127.0.0.1 &gt; nul

echo * Маленькое причесывание результата...
:: Зачистка безответных пингов
for %%i in (*) do find %STR2% &lt;%%i &gt;nul || del %%i

:: Причесывание оставшихся живых
for /f &quot;tokens=%TKNS% delims=[] &quot; %%i in (&#039;for %%h in ^(*^) do @type %%h ^|find &quot;[&quot;&#039;) do ren %%j &quot;%%j %%i&quot;
echo * Готово!
echo.
:: Вывод результата
::dir /b /o:d
::dir /b /o:n
:: Штатной числовой сортировки нет, поэтому мутим ея своими силами
for /l %%i in (1,1,254) do if exist %1.%%i (dir /b %1.%%i) else if exist &quot;%1.%%i *&quot; (dir /b &quot;%1.%%i *&quot;)

:: Убираем за собой
echo Y | del * &gt;nul
cd ..
rd %1
popd
exit /b

:usage
echo Использование: %~nx0 ^&lt;маска^&gt;
echo где ^&lt;маска^&gt; ~= N.N.N ^(e.g. 192.168.99^)
echo.
echo Описание: Сканирует подсеть класса C на предмет живых хостов.
exit /b</code></pre></div>]]></description>
			<author><![CDATA[null@example.com (vors)]]></author>
			<pubDate>Fri, 29 Jun 2012 09:06:28 +0000</pubDate>
			<guid>https://forum.script-coding.com/viewtopic.php?pid=61272#p61272</guid>
		</item>
	</channel>
</rss>
