Понадобилась возможность включать компьютер по сети. Вроде бы техника отработанная - называется WoL (Wake on Lan). Однако у меня стоит дома роутер D-Link DI-624. И мне нужно посылать "магический пакет" извне, из интернета - чтобы "пробудить" компьютер дома. NAT тут, ясен пень, не покатит - покуда комп выключен и не имеет айпишника, роутер просто не будет знать, куда именно пересылать пакет. NAT по MAC адресам? Может, и есть такой в природе, но я ни разу не слышал. Широковещательная рассылка? Наверное. Но только роутер, как выяснилось, этого не поддерживает. При попытке ввести в параметры NAT (виртуальный сервер) адреса вида 192.168.0.255 тут же получил ошибку от роутера - мол, такой адрес нельзя; нужно в диапазоне 1-254... И вот тут-то удалось-таки "победить" строптивый роутер. Все проверки на валидность у него сделаны на java-script, внедрённом в веб-интерфейс. И после проверок данные отправляются POST-запросом роутеру.
Проблема решилась ручной отправкой нужного POST-сообщения роутеру - в обход его собственной веб-формы. Естественно, в HTTP заголовок при этом нужно включить авторизационные данные админа - иначе роутер просто не примет такой пакет. В результате несложной манипуляции в правилах "виртуальных серверов" роутера оказывается нужная строчка. И - что самое забавное - она работает!
Вот заготовленный и поправленный заголовок, который я отправляю роутеру (естественно, без реальной аутентификации - а также я поправил в самих отправляемых данных параметр pubPort (66666 - такого порта, естественно, не существует; у меня реальный стоит другой))
POST /adv_virtual.cgi HTTP/1.1
Host: 192.168.0.5
User-Agent: Mozilla/5.0 (; U;; ru; rv:1.9) Gecko/2008052906 Firefox/3.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: ru,en-us;q=0.7,en;q=0.3
Accept-Encoding: gzip,deflate
Accept-Charset: windows-1251,utf-8;q=0.7,*;q=0.7
Keep-Alive: 300
Referer:
http://192.168.0.5/adv_virtual.cgiAuthorization: Basic бла-бла-бла (тут имя и пароль согласно Basic аутентификации)
Content-Type: application/x-www-form-urlencoded
Connection: keep-alive
Content-Length: 157
editRow=21&delrow=-1&enable=1&name=WoW&ip=255.255.255.255&protocol=17&priPort=9&pubPort=66666&schd=0&hour1=0&min1=0&am1=0&hour2=0&min2=10&am2=0&day1=0&day2=0
Этот заголовок я просто сохранил в файл postrouter.txt, а затем отправил его серверу с помощью нехитрой команды:
cat "postrouter.txt" | nc 192.168.0.5 80
Теперь мой роутер исправно пересылает udp-пакеты, направленные на указанный публичный порт, по широковещательному адресу. И - как показала проверка - позволяет без проблем работать поверх него Wake-on-Lan.