Понадобилось устроить шейпер на какой-нить убердешевой железке. Железкой планировался быть DIR-320 от известного китайского производителя. Но внезапно вместо хорошего и простого DIR-320 приехал ужасный и непонятный DIR-320NRU и начались проблемы.
Изначально идея была проста: ставим OpenWRT и рулим как хотим. Но поставить на NRU OpenWRT пока не представляется возможным, формат загрузчика непонятный, признаков squashfs в прошивке я беглым взглядом не нашел. Да и времени искать, как-то не оказалось. Поковырявшись в родной прошивке, стало ясно, что для выполнения задачи все необходимые инструменты (читай: tc) в ней есть. Вообще в родной прошивке дофига чего есть, даже man-страницы имеют место наличествовать.
Методом научного тыка и какой-то матери, было установлено, что все изменяемые настройки хранятся в папке /etc/default, (коя является симлинком на /tmp/etc/default, впрочем суть). Все файлы лежащие в этой папке аккуратным образом запаковываются и записываться в nvram командой /usr/sbin/saveconfig, а загружаются (в т.ч. и при старте системы) соответственно /usr/sbin/loadconfig, cat присутствует, chmod тоже, проблем со скриптами нет.
Зато есть проблемы с запуском скриптов при загрузке. Поковырявшись еще немного, обнаружился файл /etc/default/config.json (вру конешн, такое извращение не найти при первом осмотре сущий грех) и демон /bin/resident, который этот конфиг парсит и выполняет всякое в конфиге этом прописанное. Написан он по всей видимости небрежно и даже не китайцами, а индусами или что вероятнее индо-русами (Привет DLink.ru!) строки из файла сразу же пихает на выполнение. Тут-то и прешла инженерная мысль подменить какую-нить строку на скрипт. Первая попавшаяся опция была DMZ-хост — меняем содержимое config.json вида:
"dmz": { "enable": true, "ip": "192.168.0.2" }, |
на
"dmz": { "enable": true, "ip": "`/etc/default/shape.sh`" }, |
resident это все проглатывает и вместо блабла -DNAT —to 192.168.0.1, запускает наш скрипт. А если скрипт возвращает правильный ip-адрес, то еще и DMZ-хост прописывается правильно. Вуаля!
Ну и немного кода на последок:
/etc/default/shape.sh
tc qdisc del dev br0 root tc qdisc add dev br0 root handle 1: htb default 2 tc class add dev br0 parent 1: classid 1:1 htb rate 10mbps tc class add dev br0 parent 1:1 classid 1:2 htb rate 100kbps for ip in `cat /etc/default/254`;do tc class add dev br0 parent 1:1 classid 1:${ip} htb rate 100kbps tc filter add dev br0 parent 1: protocol ip prio 1 u32 match ip dst 192.168.0.${ip}/32 flowid 1:${ip} done echo cat /etc/default/DMZ.txt led wps progress |
сам шейпер, DMZ хост берестся из файла DMZ.txt, /etc/default/254 — последние байты адресов (2 3 4 5 итд)
последней строкой включаем на моргание внутреннюю неонку, чтобы раздражала и нервировала
Скрипт для подмены
echo Set DMZ Host to 9.9.9.9 via WebIF and run me again! echo Use /etc/default/DMZ.txt to set DMZ Host IP sed -i s/9.9.9.9/"\`\/etc\/default\/shape.sh\`"/g /etc/default/config.json saveconfig |
sed для нас так же оставлен, что не может не радовать.
А больше ничего и не надо. Работает примерно так: настраиваем все как надо, прописываем DMZ-host в 9.9.9.9
запускаем /etc/default/modify.sh
перезагружаем роутер путем выдергивания и вдергивания кабеля.
P.S.
Да, подключаться telnet,
скрипты пихать:
cat > /etc/default/script.sh |
вводим или копируем сильно дофига текста
Ctrl+D
готово
ну и не забываем chmod +x /etc/default/*sh
P.P.S.
А вообще можно еще много чего навертеть, но мне без надобности