Как заставить DHCP роутера сообщать о подключении устройства
Добавлено: Ср дек 17, 2014 1:37 pm
Задался я как то целью контролировать момент подключения устройства к сети. В частности нужно было при включении ТВ включать еще и спутниковый ресивер. Также при появлении заданных устройств с wifi переключать определенные режимы, например выключать "никого нет дома".
Модный в последнее время модуль ESP8266 можно держать вообще выключенным. Сработал геркон, включилось питание, модуль подключился к сети и выключился, а MD уже знает, этож какая экономия на батарейках.
Конечно можно в модуле “Устройства Online” пинговать устройства ежесекундно, но зачем если можно заставить роутер сообщать о моменте выдления им ip-адреса устройству в момент подлючения.
На современных прошивках на роутерах в качестве DHCP-сервера используется dnamasq. Это легковесный кэширующий DNS-, DHCP- и TFTP-сервер “три в одном”. Он умеет исполнять заданный скрипт при возниковениии любых изменений в DHCP таблицах, что мне и нужно. К сожалению на официальной прошивке не удалось, поэтому все делал на Tomatousb.
Создал вот такой простейший сценарий в админке MD с назваием “dhcp”:
Далее все делал на роутере.
Чтобы после перезагрузки скрипт никуда не исчезал, включил jffs: Administration - JFFS - Enable
Создал скрипт /jffs/scripts/dhcp.sh который будет отсылать события на MD:Тут надо пояснить про кучу проверок. Дело в том что dnamasq вызывает скрипт периодически (у меня каждые 30 минут), при этом в параметрах вызова скрипта будет стоять флаг $1=“old” и передается $DNSMASQ_TIME_REMAINING - оставшееся время до конца аренды IP, и не важно что клиент уже мог отключиться. Если за то время пока аренда действует клиент снова подключится, скрипту будет передан тотже флаг “old”, однако время аренды начнет отсчитываться заново. Експериментально выявлено что $DNSMASQ_SUPPLIED_HOSTNAME и $DNSMASQ_VENDOR_CLASS также передаются только когда открывается ареда. Поэтому все нужно перепроверить чтобы лишний раз не заваливать MD ложными сообщениями.
Три топора скрипту:
Теперь нужно сказать сервису dnamasq чтобы запускал данный скрипт. Через web-интерфейс
(Tomato) Advanced - DHCP/DNS - Custom configuration: http://victek.is-a-geek.com/virtual/tom ... cpdns.html
(dd-wrt) Services - Additional DNSMasq Options: http://www.dd-wrt.com/demo/Services.asp
добавить параметр dhcp-script=/jffs/scripts/dhcp.sh
Либо напрямую в nvram:
В итоге в конце конфигурационного файла /etc/dnsmasq.conf должна добавится нужная строчка:
dhcp-script=/jffs/scripts/dhcp.sh
Это всё.
Картинка для наглядности:
Модный в последнее время модуль ESP8266 можно держать вообще выключенным. Сработал геркон, включилось питание, модуль подключился к сети и выключился, а MD уже знает, этож какая экономия на батарейках.
Конечно можно в модуле “Устройства Online” пинговать устройства ежесекундно, но зачем если можно заставить роутер сообщать о моменте выдления им ip-адреса устройству в момент подлючения.
На современных прошивках на роутерах в качестве DHCP-сервера используется dnamasq. Это легковесный кэширующий DNS-, DHCP- и TFTP-сервер “три в одном”. Он умеет исполнять заданный скрипт при возниковениии любых изменений в DHCP таблицах, что мне и нужно. К сожалению на официальной прошивке не удалось, поэтому все делал на Tomatousb.
Создал вот такой простейший сценарий в админке MD с назваием “dhcp”:
Код: Выделить всё
$process=$params['process']; // =add/old/del
$mac=$params['mac'];
$ip=$params['ip'];
$host=$params['host'];
if (!$host) {
say("Присоединилось не известное устройство, присвоен IP:".$ip);
} else {
say("Присоединилось устройство: ".$host);
}
Чтобы после перезагрузки скрипт никуда не исчезал, включил jffs: Administration - JFFS - Enable
Создал скрипт /jffs/scripts/dhcp.sh который будет отсылать события на MD:
Код: Выделить всё
#!/bin/sh
#$1 = process are:
# "add" (means a lease has been created),
# "del" (means it has been destroyed)
# "old" (notification of an existing lease when dnsmasq starts
# or a change to MAC address or hostname of an existing lease
# (also, lease length or expiry and client-id, if leasefile-ro is set)
#$2 = MAC address of the host (or DUID for IPv6)
#$3 = IP address
#$4 = hostname, if known
let statleasetime=`nvram get dhcpd_slt`*60 #all parameters stored in nvram: dhcpd_slt=3600
let guestleasetime=`nvram get dhcp_lease`*60 #all parameters stored in nvram: dhcp_lease=1440
md="http://192.168.1.25/objects/?script=dhcp"
if [ $1='old' ]; then
if [ $DNSMASQ_SUPPLIED_HOSTNAME ]; then
wget -O - -q $md"&process="$1"&mac="$2"&ip="$3"&host="$4
elif [ $DNSMASQ_VENDOR_CLASS ]; then
wget -O - -q $md"&process="$1"&mac="$2"&ip="$3"&host="$4
elif [ $DNSMASQ_TIME_REMAINING == $statleasetime ]; then
wget -O - -q $md"&process="$1"&mac="$2"&ip="$3"&host="$4
elif [ $DNSMASQ_TIME_REMAINING == $guestleasetime ]; then
wget -O - -q $md"&process="$1"&mac="$2"&ip="$3"&host="$4
fi
elif [ $1='add' ]; then
wget -O - -q $md"&process="$1"&mac="$2"&ip="$3"&host="$4
fi
Три топора скрипту:
Код: Выделить всё
chmod 777 /jffs/scripts/dhcp.sh
(Tomato) Advanced - DHCP/DNS - Custom configuration: http://victek.is-a-geek.com/virtual/tom ... cpdns.html
(dd-wrt) Services - Additional DNSMasq Options: http://www.dd-wrt.com/demo/Services.asp
добавить параметр dhcp-script=/jffs/scripts/dhcp.sh
Либо напрямую в nvram:
Код: Выделить всё
nvram set dnsmasq_custom=dhcp-script=/jffs/scripts/dhcp.sh
nvram commit
dhcp-script=/jffs/scripts/dhcp.sh
Это всё.
Картинка для наглядности: