Anonymоus
03-10-2011, 06:35
По мотивам этой (http://forum.oszone.net/thread-217000.html) темы.
В связи с тем, что PowerShell не владею, захотел попробовать реализовать подобный сканер средствами обычного командного интерпретатора. В итоге получился вот такой скрипт, многопоточность технически реализована созданием другого скрипта при старте многопоточного сканирования и запуском его многочисленных копий без создания отдельного окна с помощью Start с ключом /B.
Все активные IP записываются в файл ip.log. Начальная и конечная точки диапазона для сканирования задаются в начале скрипта, там же можно указать число одновременных потоков и паузу в секундах между циклами. В ходе тестирования диапазона из 512 адресов один поток показал результат в 7 минут, десять потоков справились меньше, чем за минуту.
Известные недоработки и баги:
• Если ping выдает в качестве ответа что-то вроде "Ответ от XX.XX.XX.XX: Заданная сеть недоступна." - это будет считаться успешным пингом, errorlevel показывает нулевое значение. Обойти это можно, просеивая ответ ping с помощью find, но это неоправданно повысит нагрузку на процессор при большом количестве потоков. UPD: Добавил в скрипт опциональное включение проверки.
@Echo Off
::Многопоточный сканер сети на bat
::Anonymous, 2011
::Начало диапазона
Set IPMin=192.168.49.0
::Конец диапазона
Set IPMax=192.168.50.255
::Число потоков
Set Threads=15
::Таймаут между циклами, сек.
Set Timeout=1
::Тщательная проверка ответа ping
::(Увеличивает время выполнения и повышает нагрузку на процессор)
Set UseFind=false
For /F "tokens=1,2,3,4 delims=." %%A In ("%IPMin%") Do (
Call :isValid %%A %%B %%C %%D
Set MinA=%%A
Set MinB=%%B
Set MinC=%%C
Set MinD=%%D
)
For /F "tokens=1,2,3,4 delims=." %%A In ("%IPMax%") Do (
Call :isValid %%A %%B %%C %%D
Set MaxA=%%A
Set MaxB=%%B
Set MaxC=%%C
Set MaxD=%%D
)
Call :Compare %MinA% %MinB% %MinC% %MinD% %MaxA% %MaxB% %MaxC% %MaxD%
If %ErrorLevel%==1 Echo Конечный адрес диапазона меньше начального&Pause&Exit
Set A=%MinA%&Set B=%MinB%&Set C=%MinC%&Set D=%MinD%
Set /A Timeout+=1
Set Complete=0
If %Threads% LSS 2 GoTo SingleThread
Call :CreateThread
SetLocal EnableDelayedExpansion
:Pinger
For /L %%P In (1,1,%Threads%) Do (
Start /B thread.bat !A!.!B!.!C!.!D!
Title Сканируем !A!.!B!.!C!.!D!...
If !Complete!==1 Echo Сканирование закончено&Pause&Exit
Call :Increase
If !A!.!B!.!C!.!D!==%MaxA%.%MaxB%.%MaxC%.%MaxD% Set Complete=1
)
Ping -n %Timeout% 127.0.0.1>nul
GoTo Pinger
:SingleThread
If %%UseFind%==true (
ping -n 1 -w 1000 %A%.%B%.%C%.%D%|Find "TTL=">nul
) Else (
ping -n 1 -w 1000 %A%.%B%.%C%.%D%>nul
)
If Not %ErrorLevel%==1 (Echo %A%.%B%.%C%.%D%>>ip.log)
Title Сканируем %A%.%B%.%C%.%D%...
If %Complete%==1 Echo Сканирование закончено&Pause&Exit
Call :Increase
If %A%.%B%.%C%.%D%==%MaxA%.%MaxB%.%MaxC%.%MaxD% Set Complete=1
GoTo SingleThread
:isValid
Set IP=%*
Set i=0
:Check
Set /A i+=1
For /F "tokens=1,*" %%A In ("%IP%") Do (
If %%A GTR 255 Echo Ни один сегмент IP-адреса не может быть больше 255&Pause&Exit
If Not "%%B"=="" (Set IP=%%B && Goto Check)
)
If Not %i%==4 Echo Проверьте правильность написания IP-адреса&Pause&Exit
Exit /B 0
:Compare
If %1 GTR %5 (Exit /B 1) Else (
If %2 GTR %6 (Exit /B 1) Else (
If %3 GTR %7 (Exit /B 1) Else (
If %4 GTR %8 (Exit /B 1)
)))
If %IPMin%==%IPMax% Echo Начало и конец диапазона совпадают&Pause&Exit
Exit /B 0
:Increase
Set /A D+=1
If %D% GTR 255 (
Set D=0
Set /A C+=1
)
If %C% GTR 255 (
Set C=0
Set /A B+=1
)
If %B% GTR 255 (
Set B=0
Set /A A+=1
)
If %A% GTR 255 (Exit /B 1)
Exit /B 0
:CreateThread
Echo @Echo Off>thread.bat
If %UseFind%==true (
Echo ping -n 1 -w 1000 %%1^|Find "TTL="^>nul>>thread.bat
) Else (
Echo ping -n 1 -w 1000 %%1^>nul>>thread.bat
)
Echo If Not %%ErrorLevel%%==1 (Echo %%1^>^>ip.log)>>thread.bat
Echo Exit>>thread.bat
Exit /B
В связи с тем, что PowerShell не владею, захотел попробовать реализовать подобный сканер средствами обычного командного интерпретатора. В итоге получился вот такой скрипт, многопоточность технически реализована созданием другого скрипта при старте многопоточного сканирования и запуском его многочисленных копий без создания отдельного окна с помощью Start с ключом /B.
Все активные IP записываются в файл ip.log. Начальная и конечная точки диапазона для сканирования задаются в начале скрипта, там же можно указать число одновременных потоков и паузу в секундах между циклами. В ходе тестирования диапазона из 512 адресов один поток показал результат в 7 минут, десять потоков справились меньше, чем за минуту.
Известные недоработки и баги:
• Если ping выдает в качестве ответа что-то вроде "Ответ от XX.XX.XX.XX: Заданная сеть недоступна." - это будет считаться успешным пингом, errorlevel показывает нулевое значение. Обойти это можно, просеивая ответ ping с помощью find, но это неоправданно повысит нагрузку на процессор при большом количестве потоков. UPD: Добавил в скрипт опциональное включение проверки.
@Echo Off
::Многопоточный сканер сети на bat
::Anonymous, 2011
::Начало диапазона
Set IPMin=192.168.49.0
::Конец диапазона
Set IPMax=192.168.50.255
::Число потоков
Set Threads=15
::Таймаут между циклами, сек.
Set Timeout=1
::Тщательная проверка ответа ping
::(Увеличивает время выполнения и повышает нагрузку на процессор)
Set UseFind=false
For /F "tokens=1,2,3,4 delims=." %%A In ("%IPMin%") Do (
Call :isValid %%A %%B %%C %%D
Set MinA=%%A
Set MinB=%%B
Set MinC=%%C
Set MinD=%%D
)
For /F "tokens=1,2,3,4 delims=." %%A In ("%IPMax%") Do (
Call :isValid %%A %%B %%C %%D
Set MaxA=%%A
Set MaxB=%%B
Set MaxC=%%C
Set MaxD=%%D
)
Call :Compare %MinA% %MinB% %MinC% %MinD% %MaxA% %MaxB% %MaxC% %MaxD%
If %ErrorLevel%==1 Echo Конечный адрес диапазона меньше начального&Pause&Exit
Set A=%MinA%&Set B=%MinB%&Set C=%MinC%&Set D=%MinD%
Set /A Timeout+=1
Set Complete=0
If %Threads% LSS 2 GoTo SingleThread
Call :CreateThread
SetLocal EnableDelayedExpansion
:Pinger
For /L %%P In (1,1,%Threads%) Do (
Start /B thread.bat !A!.!B!.!C!.!D!
Title Сканируем !A!.!B!.!C!.!D!...
If !Complete!==1 Echo Сканирование закончено&Pause&Exit
Call :Increase
If !A!.!B!.!C!.!D!==%MaxA%.%MaxB%.%MaxC%.%MaxD% Set Complete=1
)
Ping -n %Timeout% 127.0.0.1>nul
GoTo Pinger
:SingleThread
If %%UseFind%==true (
ping -n 1 -w 1000 %A%.%B%.%C%.%D%|Find "TTL=">nul
) Else (
ping -n 1 -w 1000 %A%.%B%.%C%.%D%>nul
)
If Not %ErrorLevel%==1 (Echo %A%.%B%.%C%.%D%>>ip.log)
Title Сканируем %A%.%B%.%C%.%D%...
If %Complete%==1 Echo Сканирование закончено&Pause&Exit
Call :Increase
If %A%.%B%.%C%.%D%==%MaxA%.%MaxB%.%MaxC%.%MaxD% Set Complete=1
GoTo SingleThread
:isValid
Set IP=%*
Set i=0
:Check
Set /A i+=1
For /F "tokens=1,*" %%A In ("%IP%") Do (
If %%A GTR 255 Echo Ни один сегмент IP-адреса не может быть больше 255&Pause&Exit
If Not "%%B"=="" (Set IP=%%B && Goto Check)
)
If Not %i%==4 Echo Проверьте правильность написания IP-адреса&Pause&Exit
Exit /B 0
:Compare
If %1 GTR %5 (Exit /B 1) Else (
If %2 GTR %6 (Exit /B 1) Else (
If %3 GTR %7 (Exit /B 1) Else (
If %4 GTR %8 (Exit /B 1)
)))
If %IPMin%==%IPMax% Echo Начало и конец диапазона совпадают&Pause&Exit
Exit /B 0
:Increase
Set /A D+=1
If %D% GTR 255 (
Set D=0
Set /A C+=1
)
If %C% GTR 255 (
Set C=0
Set /A B+=1
)
If %B% GTR 255 (
Set B=0
Set /A A+=1
)
If %A% GTR 255 (Exit /B 1)
Exit /B 0
:CreateThread
Echo @Echo Off>thread.bat
If %UseFind%==true (
Echo ping -n 1 -w 1000 %%1^|Find "TTL="^>nul>>thread.bat
) Else (
Echo ping -n 1 -w 1000 %%1^>nul>>thread.bat
)
Echo If Not %%ErrorLevel%%==1 (Echo %%1^>^>ip.log)>>thread.bat
Echo Exit>>thread.bat
Exit /B