• - это CraftDuino - наш вариант полностью Arduino-совместимой платы.
  • CraftDuino - настоящий конструктор, для очень быстрого прототипирования и реализации идей.
  • Любая возможность автоматизировать что-то с лёгкостью реализуется с CraftDuino!
Просто добавьте CraftDuino!
подписаться на RSS-ленту

Превращаем ADSL-модем в Ethernet-шилд для Arduino/CraftDuino


0x0 — введение
0x1 — разбираем :)
0x2 — знакомимся с программной частью
0x3 — формат прошивки
0x4 — модифицируем файловую систему
0x5 — пишем первую программу
0x6 — последовательный порт
0x7 — заключение
Превращаем ADSL-модем в Ethernet-шилд

Возможно кто-нибудь помнит, как на новогодних каникулах мы проводили исследования ADSL-модема на базе Linux — ZTE ZXDSL831AII (подобен D-link DSL-2500U) и при выводе последовательного интерфейса я обмолвился о возможности превращения модема в своеобразный Ethernet-шилд.
Чтож, настала пора это сделать!



В принципе, задача выглядит просто, но при её решении я столкнулся с несколькими подводными камнями, которые неплохо отняли время на своё решение :)

Основная идея превращения модема в Ethernet-шилд очень проста — нужно всего-лишь запустить на модеме программу, которая будет слушать определённый сетевой порт и при подключении выдавать в него данные из последовательного порта и наоборот, передавать принятые данные в последовательный порт.
Разумеется, настоящий Ethernet-шилд позволяет Arduino/CraftDuino работать не только в режиме сервера, но и клиента ( слать запросы в google и писать в twitter) — этого данное решение пока не позволяет, хотя, думаю всё зависит от программы, которую вы запустите на ADSL-модеме ;)
Данное же решение подойдёт, если вам требуется управлять своим контроллером через Ethernet. Например, на базе этого решения можно построить настоящий умный дом :) Короче, всё ограничивается вашей фантазией ;)

А если у вас есть под рукой Wi-Fi-роутер D-Link DIR-320, то всё вообще становится намного проще. На него можно установить прошивку от Олега (http://wl500g.info), OpenWRT (http://openwrt.org) или dd-wrt (http://www.dd-wrt.com)
и превратить свой роутер в настоящего робота!
Идея остаётся та же — на роутере запускается программа трансляции пакетов из сети в последовательный порт, который слушает контроллер и управляет двигателями и прочими робо-прибамбасами. Причём всё это через беспроводное Wi-Fi-соедеинение. Самое удобное, что у D-Link DIR-320 есть USB-порт, к которому можно подлкючить web-камеру (поддерживающую UVC) и с помощью mjpeg-streamer передавать видеокартинку!


Итак, нам нужна программа-прокси слушающая сокет и передающая принятые данные в последовательный порт.

Такая программы уже есть:
ser2net.sourceforge.net — Serial to Network Proxy
но я воспользуюсь утилитой suart, написанной участником робофорума — Dead

Пересобираем программу под наш модем. У меня уже установлен toolchain для ADSL модема D-link 2500U

собираем программу
./bin/mips-linux-gcc -o suart suart.c


однако, при попытке запустить программу на модеме она последовательно выдавала ошибки:
/usr/bin/suart: can't resolve symbol 'cfmakeraw'
/usr/bin/suart: can't resolve symbol 'cfsetispeed'
/usr/bin/suart: can't resolve symbol 'tcflush'


так что, пришлось немного модифицировать программу.
Скачать исходник и готовую программу можно здесь:
suart-DSL-2500.zip

По-умолчанию, программа слушает 3000-й порт и перебрасывает данные на /dev/ttyS0 на скорости 115200.
Эти значения можно изменить с помощью параметров командной строки:
./suart -?
Suart is tool that allow you to tunnel a local serial connection over a network

Usage: suart [-s<serial_port>] [-p<socket_addr>] [-b<baudrate>] [-d] [-?]

   -s<serial_port> Set serial port, default is /dev/ttyS0
   -p<socket_addr> Set socket address, default is 3000
   -b<baudrate> Set serial port baudrate (9600/19200/38400/57600/115200), default is 115200
   -d Show debug info - transferred data
   -w<sec> wait seconds befor run, default is 0
   -? (-h) Show this help page

Example: suart -s/dev/ttyS1 -p3005 -b9600 -d


но для нашего модема всё подходит и программу можно запускать без параметров.

Итак, у вас уже есть программа, которую нужно запихнуть в модем. Для этого нужно модифицировать его файловую систему.

Распаковываем корневую файловую систему (можно взять файл rootfs из предыдущих примеров например, вот этот — sq7.bin).
Напоминаю, что распаковку нужно делать под суперпользователем root ;)

У нас появляется директория
squashfs-root
копируем нашу программу suart в каталог /usr/bin/
(туда же скопируйте программу sleep, которая принимает в качестве параметра число секунд на которые нужно уснуть системе — она нам пригодится )
sleep-DSL-2500.zip

Но так как мы запихнули аж две дополнительных программы — размер корневой файловой системы вырастет и прошивка на модеме скорее всего не запустится. Всё просто — нужно удалить что-нибудь ненужное.
Например, картинки из веб-интерфейса!
переходим в /webs/ и видим много gif-ок
выполним команду
for i in *.gif; do > $i; done;

файлы никуда не делись, но теперь имеют нулевой размер.

Однако, если просто запустить программу на модеме — достучаться до 3000-го порта не получится! Всё дело в файрволе(!!!) iptables, который работает на модеме.

если проверить порт с помощью nmap-а:
nmap -v 192.168.1.1 -p 3000

то он выдаст, что порт открыт, но фильтруется и подключиться к нему не получится :(

Окончательно проверить догадку относительно файрвола просто — можно убить http (командой kill -9) и запустить suart на 80-м порту
# /usr/bin/suart -p80

и всё заработает :)

Придётся разбираться с iptables. Как звучит-то: настроить файрвол на модеме :)))

Посмотреть существующие настройки можно командой:
# /bin/iptables --list
Chain INPUT (policy ACCEPT)
target     prot opt source               destination
ACCEPT     udp  --  anywhere             anywhere            udp dpt:5100
ACCEPT     udp  --  anywhere             anywhere            udp dpt:1900
ACCEPT     udp  --  anywhere             anywhere            udp dpt:5431
ACCEPT     tcp  --  anywhere             anywhere            tcp dpt:5431
ACCEPT     all  --  anywhere             anywhere            state RELATED,ESTAB
LISHED
ACCEPT     udp  --  anywhere             anywhere            udp dpt:tftp
ACCEPT     tcp  --  anywhere             anywhere            tcp dpt:telnet
ACCEPT     icmp --  anywhere             anywhere            icmp echo-request
ACCEPT     tcp  --  anywhere             anywhere            tcp dpt:www
ACCEPT     tcp  --  anywhere             anywhere            tcp dpt:ftp
DROP       all  --  anywhere             anywhere

Chain FORWARD (policy ACCEPT)
target     prot opt source               destination

Chain OUTPUT (policy ACCEPT)
target     prot opt source               destination

Ага - в цепочке INPUT видим последнюю инструкцию 
DROP       all  --  anywhere             anywhere


В принципе, можно просто очистить всю таблицу командой:
/bin/iptables -F 


Но это не наш метод :)

Узнаем номер DROP-а, чтобы его удалить:
# /bin/iptables --list --line-numbers
Chain INPUT (policy ACCEPT)
num  target     prot opt source               destination
1    ACCEPT     udp  --  anywhere             anywhere            udp dpt:5100
2    ACCEPT     udp  --  anywhere             anywhere            udp dpt:1900
3    ACCEPT     udp  --  anywhere             anywhere            udp dpt:5431
4    ACCEPT     tcp  --  anywhere             anywhere            tcp dpt:5431
5    ACCEPT     all  --  anywhere             anywhere            state RELATED,
ESTABLISHED
6    ACCEPT     udp  --  anywhere             anywhere            udp dpt:tftp
7    ACCEPT     tcp  --  anywhere             anywhere            tcp dpt:telnet

8    ACCEPT     icmp --  anywhere             anywhere            icmp echo-requ
est
9    ACCEPT     tcp  --  anywhere             anywhere            tcp dpt:www
10   ACCEPT     tcp  --  anywhere             anywhere            tcp dpt:ftp
11   DROP       all  --  anywhere             anywhere

Chain FORWARD (policy ACCEPT)
num  target     prot opt source               destination

Chain OUTPUT (policy ACCEPT)
num  target     prot opt source               destination


Удаляем DROP (11-е правило в цепочке INPUT):
/bin/iptables -D INPUT 11


Остайтся открыть 3000-й порт:
/bin/iptables  -A OUTPUT -p tcp -m tcp --dport 3000 -j ACCEPT
/bin/iptables  -A INPUT -p tcp -m tcp --sport 3000 -j ACCEPT


Проверяем — работает!
Запихнём эти команды в файл /usr/bin/mytest
#!/bin/sh

echo "[i] RoboCraft is cool!"

echo "[i] edit iptables ..."
/bin/iptables -D INPUT 11
/bin/iptables -A OUTPUT -p tcp -m tcp --dport 3000 -j ACCEPT
/bin/iptables -A INPUT -p tcp -m tcp --sport 3000 -j ACCEPT
echo "[i] iptables done!"


Остаётся прописать выполнение этих команд и последующий вызов suart-а в автозагрузку.

Сначала я пробовал запихнуть это дело в /etc/init.d/rcS
мучал его и так и эдак, пробовал ставить в конце & — чтобы программа запускалась в фоновом режиме.
Добавлял в suart параметр w который вызывал задержку(в секундах), вставлял в suart fork() — ни в какую!

В итоге, последняя редакция rcS

#! /bin/sh

PATH=/sbin:/bin
export PATH

mount -t proc proc /proc
/bin/mount -a
#/sbin/inetd

echo "[i] Start..."
#/usr/bin/suart -w30
#echo "[i] Ok. Wait 30 sec..."


А где же вызов программы? Всё просто — обратите внимание на лог загрузки модема, который можно посмотреть через последовательный порт.

Если использовать вышеприведённый rcS, то строчка
[i] Start...
будет сразу после строчки
Algorithmics/MIPS FPU Emulator v1.5

а iptables, похоже стартуют позже

обратите внимание на строчку
==>   Bcm963xx Software Version:


она отыскалась в здоровущем (аж целый мегабайт!) файле
/bin/cfm

Я решил сделать ход конём — переименовываем файл /bin/cfm в /bin/cfm0
а на его место запихнул скрипт следующего содержания:
#! /bin/sh

echo "[i] CFM..."
/bin/cfm0 &
echo "[i] my start..."
/usr/bin/sleep 30 && /usr/bin/mytest
/usr/bin/suart


Как видим, он запускает оригинальный /bin/cfm0 в фоновом режиме, а потом ждёт 30 секунд и запускает /usr/bin/mytest, который прописывает дополнительные настройки iptables, а затем и наш /usr/bin/suart

Не забудем сделать скрипт исполняемым и… всё! Можно паковать прошивку!

выполняем команду упаковки корневой файловой системы:
./mksquashfs squashfs-root/ sq8.bin -be  -no-fragments -noI -all-root -noappend -lzma -b 65536


получаем sq8.bin

далее используем мою утилиту packImage.exe из набора
ParseImage

и генерируем файл прошивки.
для ZTE ZXDSL831AII:
packImage.exe bcm.bin cfe.bin sq8.bin kernel.bin
move result.bin result-sq8-suart.bin


получаем result-sq8-suart.bin

Заходим в веб-интерфейс модема, вкладка Management -> Update firmware
указываем наш файл result-sq8-suart.bin и ждём.

Если смотреть на последовательно порту лог загрузки то мы увидим следующее:

...
init started:  BusyBox v1.00 (2008.01.31-12:18+0000) multi-call binary
Algorithmics/MIPS FPU Emulator v1.5
[i] Start...


BusyBox v1.00 (2008.01.31-12:18+0000) Built-in shell (msh)
Enter 'help' for a list of built-in commands.


Loading drivers and kernel modules... 

bcm_enet: module license 'Proprietary' taints kernel.
Broadcom BCM6338A2 Ethernet Network Device v0.3 Jan 31 2008 20:15:18
Config Internal PHY Through MDIO
BCM63xx_ENET: 100 MB Full-Duplex (auto-neg)
eth0: MAC Address: 00:D0:D0:86:86:B5
Broadcom BCM6338A2 USB Network Device v0.4 Jan 31 2008 20:15:20
usb0: MAC Address: 00 D0 D0 86 86 B6
usb0: Host MAC Address: 00 D0 D0 86 86 B7
[i] CFM...
[i] my start...
eth0 Link UP.
BcmAdsl_Initialize=0x800EDB88, g_pFnNotifyCallback=0x801A48C4
AnnexCParam=0x7FFF7EB8 AnnexAParam=0x00000980 adsl2=0x00000000
pSdramPHY=0xA07FFFF8, 0x9D701 0xDEADBEEF
AdslCoreHwReset: AdslOemDataAddr = 0xA07F8054
AnnexCParam=0x7FFF7EB8 AnnexAParam=0x00000980 adsl2=0x00000000
dgasp: kerSysRegisterDyingGaspHandler: dsl0 registered 
ATM proc init !!!
ip_tables: (C) 2000-2002 Netfilter core team
ip_conntrack version 2.1 (61 buckets, 0 max) - 376 bytes per conntrack
ip_conntrack_pptp version 2.1 loaded
ip_nat_pptp version 2.0 loaded
ip_conntrack_rtsp v0.01 loading
ip_ct_h323: init success
ip_nat_h323: init success
insmod: cannot open module `/lib/modules/2.6.8.1/kernel/net/ipv4/netfilter/ip_co
nntrack_tftp.ko': No such file or directory
insmod: cannot open module `/lib/modules/2.6.8.1/kernel/net/ipv4/netfilter/ip_na
t_tftp.ko': No such file or directory
ip_nat_irc: Unknown symbol needs_ip_conntrack_irc
insmod: cannot insert `/lib/modules/2.6.8.1/kernel/net/ipv4/netfilter/ip_nat_irc
.ko': Success (2): Success
ip_nat_rtsp v0.01 loading

==>   Bcm963xx Software Version: ZXDSL 831AIIV4.1.0a_E09_RU   <==

device usb0 entered promiscuous mode
br0: port 1(usb0) entering learning state
br0: topology change detected, propagating
br0: port 1(usb0) entering forwarding state
...
br0: port 3(nas_0_1_92) entering learning state
br0: topology change detected, propagating
br0: port 3(nas_0_1_92) entering forwarding state
CONSOLED launched
exit
CONSOLED exited
CONSOLED launched
exit
CONSOLED exited
CONSOLED launched
exit
br1: port 1(usb0) entering disabled state
[i] RoboCraft is cool!
[i] edit iptables ...
[i] iptables done!

полный лог — suart_loading_log.txt

Обратите внимание — когда стартует /etc/init.d/rcS (строчка [i] Start...)
и когда /bin/cfm (строчка [i] CFM... )

проверяем порт с помощью nmap-а:
nmap -v 192.168.1.1 -p 3000


и видим:
Host 192.168.1.1 appears to be up ... good.
Interesting ports on 192.168.1.1:
PORT     STATE SERVICE
3000/tcp open  ppp


отлично! порт открыт!

Пробуем подключиться:
telnet 192.168.1.1 3000

Работает!!!

Вот, собственно и всё. Разумеется, наверное можно отключить вывод отладочной информации о загрузке модема, чтобы на вход микроконтроллера не сыпались лишние данные, но, думаю, это не обязательно — просто перед своими управляющими командами нужно добавить какое-нибудь кодовое слово и всё.

Программы:
suart-DSL-2500.zip
sleep-DSL-2500.zip
sq8.bin
result-sq8-suart.bin
ParseImage

Далее: Исследование Wi-Fi-роутера TP-LINK TL-MR3020

Ссылки:
Что нам стоит «умный дом» построить. Делаем фарш из микроконтроллеров и роутера
roboforum.ru/wiki/DIR-320
roboforum.ru/forum10/topic9534.html
roboforum.ru/forum88/topic9793.html
iptables:
www.posix.ru/network/iptables/
www.opennet.ru/docs/RUS/iptables/
www.frozentux.net/iptables-tutorial/iptables-tutorial.html
программирование под Linux:
www.advancedlinuxprogramming.com
www.opennet.ru/docs/RUS/serial_guide/

Автор: Vladimir (noonv), 2011

Эксклюзивно для www.robocraft.ru
копирование на другие ресурсы и публикация
без разрешения автора запрещены.
  • +2
  • 5 июня 2011, 09:48
  • noonv

Комментарии (11)

RSS свернуть / развернуть
+
+1
Если есть полноценный процессор, крос-компилятор и внешние порты, то нафига козе баян микроконтроллер? Прогу то можно прямо линуховую написать.
Но шилд то конечно своеобразный получился — работающий на последовательном порту. SPI здесь бы лучше смотрелся бы:)
avatar

Radiolok

  • 5 июня 2011, 19:19
+
0
Какое количество внешних портов доступно у данного модема? Светодиоды?
avatar

Eruman

  • 7 июня 2011, 09:14
+
0
Круто. Изобретательское решение с iptables :)
avatar

universeroot

  • 14 июня 2011, 13:52
+
0
ЗдОрово! Спасибо за статью. А как бы вообще заменить CFM скриптами? Broadcom и вендоры как правило не дают его исходники, а этот монстр управляет всем в роутере.
avatar

rusink

  • 27 июня 2011, 21:04
+
0
почему же — на сайте Broadcom есть исходники их CFM ;)
avatar

admin

  • 28 июня 2011, 22:41
+
+1
Правда? А вы не путаете CFM с CFE? Может быть ссылочку дадите?
avatar

rusink

  • 29 июня 2011, 04:52
+
0
вы правы, я перепутал и говорил о CFE :(
avatar

admin

  • 29 июня 2011, 07:35
+
0
подскажите, плиз, уважаемые Гуру) можно ли заставить br1 — выделенный в отдельную группу интерфейс — получать сетевые настройки по DHCP? через ifconfig можно настроить фиксированный ip и gw, а если выполнить команду
dhcpc -i br1
, то вылазиет ошибка
/proc/var/fyi/wan/br1/daemonstatus: cannot create
, что понятно, т.к в папке /proc/var/fyi/wan нет ничего про br1.. Если создать ADSL подключение, то его имя появляется в папке wan — типа nas_0_8_35.
Может есть способ создать там и папку br1? Или можно запустить dhcpc в обход использования этой папки? Или может можно переименовать br1 в nas_0_8_35.

Машинка — DLink dsl-2640u/bru/c2, fw:2.05
avatar

dnov

  • 12 сентября 2011, 20:25
+
0
Помогите с прошивкой для D-link 2500u — сделал кто? Можете выложить?
avatar

Qic

  • 17 октября 2011, 20:38
+
0
Подскажите пожалуйста, как на модем добавить telnet? Сейчас при попытке подключения порт открыт, но подключение обрывается
avatar

baikaltech

  • 27 марта 2013, 10:10
комментарий был удален


Только зарегистрированные и авторизованные пользователи могут оставлять комментарии.