Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- @REM coding:OEM
- @ECHO OFF
- REM здесь надо указать путь к файлу журнала. Можно относительный, можно абсолютный.
- SET log="d:\var\logs\%~n0\%~n0.log"
- REM Журнал надо периодически чистить, делать logrotate то есть. Или можно просто удалять файл.
- REM цель только по IP (213.180.204.3), по hostname (ya.ru) нельзя, потому что:
- REM 1. связи с DNS может не быть, и соответственно имя в IP не разрешится
- REM 2. route add работает только с IP
- REM здесь указан первый IP OpenDNS
- SET target=208.67.222.222
- rem Если не надо возвращаться с резервного канала при восстановлении основного,
- rem раскомментируйте следующую строчку. В этом случае меньше будет манипуляций с таблицей маршрутов.
- rem PING %target% -n 1 >>%log% 2>&1 && EXIT /B
- REM --- настройка закончена, дальше трогать ничего не надо ---
- REM последний использованный шлюз записан в currentgw.txt. Если файла нет, будет создан.
- FOR /F "usebackq delims=" %%I IN ("currentgw.txt") DO SET currentgw=%%I
- ECHO.
- ECHO currentgw.txt: %currentgw%|tee -a %log%
- CALL :ReadRoute currentgw 0.0.0.0
- ECHO Current default route: %currentgw%|tee -a %log%
- REM Кроме, может быть, последней функции, где разбирается вывод ping-а.
- SET foundgw=
- REM небольшая вставка для мониторинга хостов
- IF EXIST "IPs_to_monitor.list" CALL :CheckHost %currentgw% && CALL :HostsMonitoring
- REM из файла gateways.list читаются IP адреса шлюзов (1 строка - 1 IP)
- REM начало цикла перебора шлюзов
- FOR /F "usebackq delims=" %%I IN ("gateways.list") DO (
- CALL :CheckGateway %%I && EXIT /B
- )
- REM собственно, если выполнение дошло сюда, значит ни через один из шлюзов цель недоступна.
- REM Либо настал конец Интернета, либо надо выбирать более лучше отличающихся провайдеров,
- REM либо просто умерла цель. Можно было бы сообщить что-н типа
- REM net send * Интернет кончился! Мы все умрём!
- REM Но я не буду.
- ECHO %DATE% %TIME% No working gateways found!
- EXIT /B
- :CheckGateway
- ECHO %DATE% %TIME% checking gateway %1|tee -a %log%
- REM проверяется связь со шлюзом
- ping %1 -n 1
- rem >>%log% 2>&1
- REM Пинги сначала идут через стандартный маршрут,
- REM поэтому пигновать что-либо за любым из роутеров бесполезно
- REM если шлюз не отвечает, продолжать нет смысла
- IF ERRORLEVEL 1 EXIT /B
- REM Шлюз отвечает, надо проверить, доступна ли через него цель (target)
- REM добавляется маршрут для цели, но только если текущий шлюз не тот же, что и проверяемый
- REM MASK 255.255.255.255 по умолчанию
- ROUTE DELETE %target% 2>&1
- ping 127.0.0.1 -n 2 >NUL
- ECHO Adding temporary route to %target% through %1|tee -a %log%
- IF "%currentgw%"=="%1" GOTO :SkipAddingTempRoute
- ROUTE ADD %target% %1 METRIC 1 2>&1 |tee -a %log%
- CALL :CheckRoute %target% %1 || EXIT /B 1
- REM если не подождать, Windows не успевает обновить таблицу маршрутов,
- REM и даже удаление перед закрывающей строчкой не удаётся с сообщением,
- REM что удалять нечего и маршрута нет.
- REM Но маршрут внезапно обнаруживается к следующему шагу цикла
- REM и не позволяет использовать следующий шлюз.
- ping 127.0.0.1 -n 2 >NUL
- :SkipAddingTempRoute
- ECHO Checking %target% availability|tee -a %log%
- REM проверка, и если ошибки нет, запись найденного работающего шлюза
- CALL :CheckHost %target% && SET foundgw=%1
- IF NOT "%currentgw%"=="%foundgw%" (
- ECHO Removing temporary route to %target%|tee -a %log%
- REM удаление временного маршрута.
- ROUTE DELETE %target% 2>&1 |tee -a %log%
- ping 127.0.0.1 -n 2 >NUL
- CALL :CheckRoute %target% %1 && ECHO Temporary route not removed!!!|tee -a %log%
- )
- ECHO Current gateway: "%currentgw%" Working gateway: "%foundgw%"|tee -a %log%
- REM foundgw устанавливается только если найден шлюз, через который доступна цель
- REM но если он совпадает с тем, что используется сейчас, менять ничего не надо
- IF "%currentgw%"=="%foundgw%" EXIT /B 0
- IF NOT "%foundgw%"=="" GOTO :SwitchGateway
- REM конец цикла перебора шлюзов
- EXIT /B 1
- :SwitchGateway
- ECHO %DATE% %TIME% Switching route to %foundgw%|tee -a %log%
- REM Удаление старого маршрута
- ECHO Removing default route|tee -a %log%
- ROUTE DELETE 0.0.0.0 2>&1 |tee -a %log%
- ping 127.0.0.1 -n 2 >NUL
- CALL :CheckRoute 0.0.0.0 && ECHO Default route not removed!|tee -a %log%
- REM Добавление нового
- ECHO Adding default route through %foundgw%|tee -a %log%
- ROUTE ADD 0.0.0.0 MASK 0.0.0.0 %foundgw% METRIC 50 2>&1 |tee -a %log%
- CALL :CheckRoute 0.0.0.0 %foundgw% || ECHO New default route not added!|tee -a %log%
- REM и запись нового в файл
- ECHO %foundgw%>currentgw.txt
- EXIT /B 0
- :ReadRoute
- rem Читает первый шлюз для %2 в переменную %1
- FOR /F "usebackq tokens=1,3" %%I IN (`route print^|FIND " %~2 "`) DO IF "%%I"=="%~2" (
- SET %~1=%%J
- EXIT /B 0
- )
- EXIT /B 1
- :CheckRoute
- rem Проверка, что в существует маршрут до %1 через %2
- rem ROUTE ADD не возвращает код ошибки, даже если маршрут добавить не удалось
- rem поэтому надо проверять, насколько удачно он добавился
- FOR /F "usebackq tokens=1,3" %%I IN (`route print^|FIND " %~1 "`) DO IF "%%I"=="%~1" (
- IF "%~2"=="" EXIT /B 0
- IF "%%J"=="%~2" EXIT /B 0
- )
- EXIT /B 1
- rem Пинг сволочь, ибо возвращает 0 даже если ему ответили no route to host
- rem Наример:
- rem c:\Scripts>PING 208.67.222.222 -n 1
- rem Pinging 208.67.222.222 with 32 bytes of data:
- rem Reply from 193.46.213.10: Destination host unreachable.
- rem Ping statistics for 208.67.222.222:
- rem Packets: Sent = 1, Received = 1, Lost = 0 (0% loss),
- rem Approximate round trip times in milli-seconds:
- rem Minimum = 0ms, Maximum = 0ms, Average = 0ms
- rem После этого errorlevel 0, видимо, потому что Lost = 0. Но связи-то нет!
- rem поэтому нужна следующая функция:
- :CheckHost
- rem FOR используется для разбора того, что пишет ping, поскольку код ошибки неадекватен.
- rem skip=3 значит, что из ответа надо пропустить первые 3 строки:
- rem пустая, обмен данными с ..., и ещё пустая.
- rem Если у Вас ответ PING выглядит по другому, эту часть надо исправлять.
- rem Например, в Vista skip=2
- FOR /F "usebackq delims==: skip=3 tokens=1,2*" %%J IN (`PING %1 -n 1`) DO (
- ECHO Pinging %1: %%J: %%K=%%L >>%log%
- rem Ping %1 -n 1 -r 4 >>%log% 2>&1
- rem Следующая строка для русской версии Windows. Если у Вас английская, её можно закомментировать.
- IF NOT ERRORLEVEL 1 IF "%%~J"=="Ответ от %1" IF "%%~K"==" число байт" EXIT /B
- rem Если у Вас русская версия Windows, можно закомментировать следующую строчку.
- IF NOT ERRORLEVEL 1 IF "%%~J"=="Reply from %1" IF "%%~K"==" bytes" EXIT /B
- rem Возможно, у Вас ping будет отвечать, используя другие слова.
- rem В этом случае во второй IF вместо Reply from надо написать то, что написано до IP,
- rem а в 3й, вместо " bytes", то, что написано между двоеточием : и знаком равенства =,
- rem включая пробелы.
- rem Если первая строчка ответа PING не соответствует нормальному ответу можно выходить,
- rem Ибо сводка неинтересна.
- EXIT /B 1
- )
- rem Если выполнение дошло до сюда, значит PING ответил меньше skip= строк.
- rem Это явно что-то ненормальное, так что стоит записать в лог.
- ECHO Last ping reply contains less than 3 lines>>%log%
- ping %1 -n 1 >>%log% 2>&1
- EXIT /B 1
- :HostsMonitoring
- ECHO Hosts monitoring...|tee -a %log%
- FOR /F "usebackq tokens=1* delims=:" %%I IN ("IPs_to_monitor.list") DO (
- CALL :CheckHost %%J && ECHO %%I %%J ok
- IF ERRORLEVEL 1 (
- ECHO Error pinging %%I: %DATE% %TIME% %%J|tee -a "d:\var\logs\link-monitoring\%%~I %%~J.log"
- IF NOT EXIST "d:\var\logs\link-monitoring\pathping %%~I %%~J %DATE%.log" START "" %comspec% /C pathping %%~J ^>"d:\var\logs\link-monitoring\pathping %%~I %%~J %DATE%.log" 2^>^&1
- ECHO %%I %%J failure
- )
- )
- EXIT /B
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement