Сбор параметров соединения со спутниковых модемов Hughes HN92XX

By | 2017-02-05

В ситуации, когда Mikrotik стоит за спутниковым модемом, резонно собирать и централизованно хранить инфу о параметрах соединения, как и в случае с GSM-модемами.
Способ реализации для спутниковых модемов Hughes HN92XX в этой заметке.

К великой радости, данные модемы показывают параметры в виде статичных html-страниц:
Окно интерфейса модема
Осталось только их скачать и распарсить.

Подготовка
В моём случае, спутниковый модем подключается к порту ether1-gateway, на котором поднят DHCP-клиент с дистанцией шлюза 1.
Соответственно, чтобы получить IP-адрес модема, нужно узнать статус DHCP-клиента и если он получил параметры, то взять из таблицы маршрутизации шлюз с метрикой 1.

Для работы с Web в Mikrotik‘ах есть команда fetch из группы tool. Команда может рабртать с HTTP, HTTPS, FTP, поддерживает Basic auth, ей можно отправлять GET-запросы с параметрами на сервер и т.д., но есть в ней фатальный недостаток — она не умеет писать результат в переменную или на какой-нибудь RAM-диск. Поиски решения проблемы, привили меня на оф. форум микротика, где в теме о DynDNS поднимался вопрос: «а не сотрётся ли до дыр флеш память если раз в 5 минут писать на флешку?». Как я понял — разработчик, ответил, что писать результат в переменную и/или сделать RAM-диск — хорошая мысль и они подумают об этом. Ветка датировалась прошлым десятилетием…

Так как основной инфой для меня является SiteID и серийный номер модема, которые не меняются так уж часто и в целях заботы о флешке, было решено делать опрос раз в, приблизительно, 7 дней.
Что значит «приблизительно»? Т. к. встроенных функций вычисления разности дат в Mikrotik’ах нет, а писать точный алгоритм длинно, муторно да и, откровенно говоря, не нужно, я принял, что в месяце 30 дней.

Ну а дальше всё просто: смотрим код html’ки и парсим функциями find/pick

Скрипт

:local serial [/system routerboard get value-name="serial-number"]
:local osver [:pick [/system resource get value-name=version] 0 [:find [/system resource get value-name=version] " "]]
:local url "example.com:443"
:local user "user"
:local pass "pass"

#Если DHCP-клиент получил адрес, значит там что-то похожее на модем, иначе не делаем ничего
if ([/ip dhcp-client find where interface="ether1-gateway" and status="bound"]!="") do={
    :local satupd 0
#Если файл существует, смотрим не просрочен ли он и если да - выставляем флаг
    if ( [:len [/file find name="modem.html"]]!=0 ) do={
        :local months ("jan","feb","mar","apr","may","jun","jul","aug","sep","oct","nov","dec");
        :local fmonth ([ :find $months [pick [/file get modem.html creation-time] 0 3] -1 ] + 1)
        :local fday [pick [/file get modem.html creation-time] 4 6]
        :local month ([ :find $months [pick [/system clock get date] 0 3] -1 ] + 1)
        :local day [pick [/system clock get date] 4 6]
#Проверка, что файл старше 7 дней
#Видел в инете полную реализацию сравнения дат, но она на полтора экрана
        if ( $month = $fmonth ) do={
            if ( ($day - 7) >= fday ) do={ :set satupd 1 }
        } else={
            if ( ($month - fmonth) > 1 ) do={ :set satupd 1
            } else={
                if ( ($day-7+30) >= fday ) do={ :set satupd 1 }
            }
        }
    } else={:set satupd 1}
#Если файла нет или он устарел
    if ( satupd=1 ) do={
#Получаем IP-адрес модема
        local modem [/ip route get  [/ip route find where dst-address~"0.0.0.0" and distance=1] gateway]
#Скачиваем страницу с системной инфой
#если такой страницы нет (на другом конце не модем, другая ревизия и т.д.),
то команда кинет исключение и скрипт завершится
        /tool fetch dst-path=modem.html mode=http [:put ("http://$modem/sys_info/")]
        :delay 1
Получаем содержимое файла в переменную (здесь, наверное, стоило бы размер файла проверить...)
        :local info [/file get modem.html contents ]
#Собственно парсим...
        :local pstart [:find $info "Site ID" 0]
        :local siteid [:pick $info ($pstart+34) [:find $info "<" ($pstart+34)]]
     
        :local pstart [:find $info "Serial Number" 0]
        :local modemsn [:pick $info ($pstart+39) [:find $info "<" ($pstart+39)]]
     
        :local pstart [:find $info "Software Release" 0]
        :local fwversion [:pick $info ($pstart+42) [:find $info "<" ($pstart+42)]]
#Скачиваем страницу с инфой о подключении
        /tool fetch dst-path=modem.html mode=http [:put ("http://$modem/sys_status/")]
        :delay 1
#Снова парсим...
        :local info [/file get modem.html contents ]
        :local pstart [:find $info "Signal Strength" 0]
        :local signal [:pick $info ($pstart+46) [:find $info " " ($pstart+46)]]
#Отправляем добытое на сервер
        /tool fetch mode=https keep-result=no user=$user password=$pass [:put ("https://$url\?serial=$serial&modemsn=$modemsn&signal=$signal&siteid=$siteid&fwversion=$fwversion")]
    }
}

Ну и теперь это можно присоседить к скрипту из заметки про GSM и в зависимости от типа подключения нам будут приходить релевантные данные.

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

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