---
author: anton
title: kako uporabiti TS ONT kot merilnik prenosa podatkov
categories: internet
tags: internet homelab sysadmin
lastmodified: 2021-12-30 21:48:00
---
V tej objavi opišem postopek uporabe optičnega modema kot merilec podatkovnega prometa.
## Uvod
Ključna prednost Gigabitnega pasivnega optičnega omrežja ([GPON](//en.wikipedia.org/wiki/Passive_optical_network)), ki se je v zadnjih letih v Sloveniji močno razširilo in uporabnikom omogočilo širokopasovni priklop v Internet, je preprostost namestitve in predvsem za operaterja cenovno ugodna infrastruktura, ko gre za nove napeljave. Površno povedano se eno optično vlakno s pasivno prizmo razcepi na več vlaken, povezanih do naročnikov, ki z operaterjevo mrežno opremo daleč stran komunicirajo na določeni valovni dolžini/barvi svetlobe. Slabost take infrastrukture pa je predvsem ta, da GPON ne temelji na obstoječi infrastrukturi. DOCSIS recimo deluje na obstoječih napeljavah za kabelsko televizijo, DSL na obstoječih telefonskih kablih, za GPON pa je potrebno nameščati popolnoma nova optična vlakna, kar se lahko pozna na računu končnega uporabnika.
Tako kot pri veliko načinih povezave naročnika v operaterjevo omrežje se tudi pri GPON pojavlja problem zaradi uporabniku nevsakdanjih načinov mrežnih povezav. Le majhen del uporabniške tehnološke opreme dejansko omogoča direktno povezavo v optično omrežje, zato po navadi vsaj pri rezidenčnih uporabnikih operater naročniku omogoča izposojo modema za pretvorbo L1 protokola iz GPON v Ethernet.
Bolj strokovno se takemu modemu v GPON omrežjih reče optični omrežni terminal (ONT). Ta ONT pa lahko kot neka operaterjeva naprava poraja vprašanja glede zasebnosti in konec koncev predstavlja zgolj še eno dodatno škatlico, ki mora stati nekje zaprašena na polici.
Zato sem ji dodal neko preprosto dodatno funkcijo: merilec prometa med notranjim domačim omrežjem in Internetom oziroma operaterjevim omrežjem. Vpogled v to statistiko je dobrodošel, da vidimo, kdaj recimo poteka najmanj prometa in ustrezno časovno omejimo velike porabnike prenosa podatkov (bittorrent protokol, zrcaljenje). Prav tako je dostop do take naprave uporaben za iskanje napak pri konfiguraciji omrežij.
## Podatki o uporabljenem modemu
Uporabljen modem je Comtrend GRG-4242U, kot piše na nalepki, in je namenjen predvsem operaterjem prav za posojo naročnikom. Podjetje namreč nima spletne trgovine ali kataloga s cenikom in na prvi pogled izgleda precej orientirano poslovanju s podjetji. Tega modela modema tudi nisem našel v nobeni trgovini pri nobenem distributerju. Povsem možno je, da gre za t. i. [izdelek z belo etiketo](//en.wikipedia.org/wiki/White-label_product), ki se ga dobiti pod drugačnimi imeni.
Na dokaj sposobni strojni opremi na Broadcomovem BCM68488 SoC z dvaintridesetbitnim Broadcomovim procesorjem BMIPS4350 MIPS arhitekture, 100 megabajti RAMa, 318 megabajti MTD spomina, od katerega je velika večina samo za branje, kar pa je omejitev datotečnega sistema ubifs in ne strojne opreme, teče Broadcomov operacijski sistem na osnovi Linux jedra različice 3.4.11-rt19 in ostalih GPL orodij (brctl, busybox), od katerih je veliko tudi spremenjenih z dodatnimi Broadcomovimi funkcijami. Izvorne kode vseh teh programov in jedra nisem našel objavljenih.
ONT je opremljen z dvema Ethernet RJ45 priključkoma, prvim 1 Gb/s in drugim 100 Mb/s, enim GPON priključkom, ki podpira pritočne hitrosti do 2,4 Gb/s in odtočne do 1,2 Gb/s in oddaja na valovni dolžini 1310 nanometrov in sprejema na valovni dolžini 1490 nanometrov. V [uradnem opisu opreme](//www.comtrend.com/dbase/upload-img/download/DS_GRG-4242u_R1%203_031721.pdf) je navedena maksimalna razdalja od operaterjeve opreme do ONTja 20 kilometrov. Modem ima vgrajeno tudi "centralo" za telefon in RJ11 priključek, torej lahko z uporabo ONTja kličemo iz klasičnih stacionarnih telefonov z uporabo VoIP.
Ugodno je, da ima ONT vgrajen USB 2.0 priključek, saj lahko na USB izmenljivem mediju hranimo datoteke, ne da bi uporabljali majhno in neučinkovito notranjo zapisljivo jffs2 shrambo.
Poleg vsega tega se proizvajalec hvali tudi z obilo programske opreme, recimo s HTTP vmesnikom za nastavitev, backdoor dostopom za operaterja ter podporo za VLAN, NAT, SNMP, TR-069, DHCP, SMB, DNS in NTP. Seveda je večina teh programov prosta programska oprema in gnezdo za programske napake v prihodnosti, zato sem jih poskusil onemogočiti čim več.
## Dostopanje do lupine modema
Na nalepki na ONT so napisani osnovni podatki za dostop do modema, seveda vsem poznana standardna kombinacija uporabniškega imena in gesla user:user in zasebni IP modema v zasebnem omrežju 192.168.8.1/24. Na modem se lahko povežemo preko HTTP vmesnika za konfiguracijo, ki za nameščanje programov seveda sploh ni uporaben, TELNETa, SSHja in celo SMB protokola, slednji verjetno za oddaljen dostop do datotek iz izmenjivega medija.
Niti po TELNET niti po SSH mi sicer ni uspelo vzpostaviti povezave do lupine, sem pa opazil UART konektor za serijsko povezavo. Ob povezavi po bootu sistem odpre poziv za prijavo, vendar tudi tam prijava ni delovala. Ima pa Linux zanimivo funkcijo [SysRq](https://en.wikipedia.org/wiki/Magic_SysRq_key), ki omogoča priklic računalnika k življenju ob slučajnem totalnem kaosu, recimo če imamo odstranljivo datoteko na vrtečem disku in sistemu zmanjka spomina ali pa če kakšen proces porablja toliko procesorskega časa, da ga niti pobiti ne moremo več. S hkratnim stiskom tipk Alt, SysRq in E recimo pobijemo vse procese. Samo to nam seveda nič ne pomaga, ker prvič nimamo tipkovnice in drugič bi pobitjem procesov bi samo ponovno prišli na login, ne?
screen /dev/ttyUSB0 115200
Prvi problem je hitro rešljiv: Funkcijo SysRq lahko na veliko Broadcomovih napravah uporabljamo kar preko UART s pošiljanjem znaka ^, ki mu sledi črka za nek SysRq ukaz. Če recimo napišemo ^E, bodo pobiti vsi procesi, vendar pa operacijski sistem takrat zazna napako (seveda, cel kup procesov je umrlo) in priročno ponudi lupino.
consoled:error:579.277:oalMsg_initWithFlags:115:connect to /var/smd_messaging_server_addr failed, rc=-1 errno=2
consoled:error:579.277:main:228:could not connect to CMS smd (ret=9002) == drop to shell for debug
BusyBox v1.17.2 (2020-08-31 18:10:51 CST) built-in shell (ash)
Enter 'help' for a list of built-in commands.
#
Ampak še vedno ta lupina ni rešitev za vse težave. Ob pojavu takih kritičnih težav namreč ni dovolj, da se samo pojavi lupina na serijskem priključku. Če končni uporabnik modema nima pojma, da ta konektor sploh obstaja, si lahko s tem bore malo pomaga. Zato imajo majhni vgrajeni računalniki v takih kritičnih primerih t. i. [psa čuvaja](//en.wikipedia.org/wiki/Watchdog_timer), fizično komponento, ki, če ne dobi ustreznega signala ustreznem časovnem obdobju, ponovno začene celoten sistem, v upanju, da se bo delovanje povrnilo v prvotno stranje. In pogosto se.
Na modemu za *hranjenje* psa čuvaja vsake toliko časa skrbi program `/bin/ct_monitor`, ki venomer teče v ozadju, ob pobitju vseh procesov pa seveda tudi sam umre, torej se sistem po tridesetih sekundah ponovno zažene. V tem času moramo torej ugotoviti način *hranjenja* psa čuvaja, drugače moramo postopek pridobitve lupine izvesti še enkrat. V primeru tega modema je to zgolj preprost ukaz `ct_monitor &`.
Na srečo modem svojo funkcijo perfektno opravlja tudi brez kopice vseh teh nepotrebnih procesov.
## Nastavitev okolja za prevajanje
Najbolj razžirjena arhitektura procesorjev za osebne računalnike je X86, ki pa ni najbolj ugodna izbira za proizvajalce vgrajene opreme. X86 je namreč znana po dolgem seznamu inštrukcij in funkcij, kar prispeva k veliki porabi elektrike in s tem k potrebi po aktivnem hlajenju, konec koncev pa tudi k fizični velikosti čipa, v katerem se nahaja procesor. Vsekakor je končnemu uporabniku bolj prijazno, da je hlajenje procesorja v modemu pasivno (brez potrebe po ventilatorju), za kar obstajajo optimizirane arhitekture, kot so RISC-V in MIPS. Prevedeni programi za osebni računalnik zato seveda ne bodo delovali na MIPS modemu.
Potrebujemo torej skupek orodij za prevajanje programov za druge arhitekture. Za vsako strojno platformo proizvajalci izdelajo t. i. verigo orodij, ki vključuje prevajalnike za programski jezik C in orodja za izdelavo knjižnic in izvršljivih datotek. Kompatibilna veriga orodij za ta modem je Broadcomov [stbgcc](//github.com/Broadcom/stbgcc-8.3/releases). V primeru, da programje izgine iz obličja Interneta, je [tukaj varnostna kopija](//git.sijanec.eu/anonymous/stbgcc-8.3).
Če zaupamo izvršljivim datotekam, ki jih ponujata Broadcom in Microsoft, lahko verigo na debianski sistem naložimo kar z ukazi:
wget https://github.com/Broadcom/stbgcc-8.3/releases/download/stbgcc-8.3-0.4/stbgcc-8.3-0.4.x86_64.deb -O/tmp/stbgcc.deb
dpkg -i /tmp/stbgcc.deb
Lahko pa program tudi prevedemo iz izvorne kode v debianski paket, ki ga potem namestimo, recimo če računalnik, na katerem bomo prevajali nima prav štiriinšestdesetbitnega X86 procesoja, kot recimo moj i686. Da ne bi še kdo zapravljal časa s tem in ima računalnik z i386 kompatibilen računalnik, pa si lahko [deb paket naloži tukaj](//cdn.sijanec.eu/etc/sw/stbgcc-8.3-0.4.deb).
apt install help2man gawk libtool-bin
wget https://github.com/Broadcom/stbgcc-8.3/releases/download/stbgcc-8.3-0.4/stbgcc-8.3-0.4_src.tar.gz -O/tmp/stbgcc.tar.gz
cd /tmp
tar -xvf stbgcc.tar.gz
cd gcc83
make # tole traja več ur
make deb
dpkg -i stbgcc-8.3-0.4.deb
Po namestitvi paketa je vse potrebno za grajenje v direktoriju `/opt/toolchains/stbgcc-8.3-0.4`. Prevjalniki in ostali programi za izdelavo izvršljivih datotek, recimo linkerji, so v `/opt/toolchains/stbgcc-8.3-0.4/bin` zato z ukazom `export PATH=$PATH:/opt/toolchains/stbgcc-8.3-0.4/bin` svoji lupni povemo, kje iskati programe.
### Nastavitev dodatne shrambe
Pred prevajanjem večjih programov je smiselno preveriti, kako jih bomo sploh prenašali na modem in če prevedni programi sploh delujejo. Za zapisljivo shrambo podatkov sem vzel nek USB ključek z dvema gigabajtoma prostora in ga kar brez particijske tabele (tu se kaže superiornost POSIX sistemov) formatiral v ext4. Sprva ni delovalo, ker operacijski sistem na modemu ne podpira ext4 dodatka `metadata\_csum`, zato je treba formatirati izmenljivi medij takole:
mkfs.ext4 /dev/sdz -O ^metadata_csum
Šele po vstavitvi ključka v modem pa lahko poženemo `mkdir /data/usb && mount /dev/sda /data/usb`. Privzeto je namreč direktorij `/data` zapisljiv v datotečni obliki jffs2.
Na računalniku sedaj prevedemo nek preprost program z ukazom `mips-linux-gcc pozdravljen_svet.c`.
### Povezava modema in računalnika
Ker modem primarno operira z mrežnimi paketi na drugem ISO/OSI nivoju, se ne moremo povezati direktno nanj -- vse pakete bo posredoval naprej operaterju. No, skoraj vse. Nekaj zasebnih IP omrežij bo obdržal zase, zato si lahko na računalniku nastavimo naslov v omrežju `192.168.8.0/24` in se povezujemo na modem na IP naslovu `192.168.8.1`.
ip addr add dev eth99 192.168.8.87/24
Za prenos datotek je bil pa meni uporaben PHP iz paketa `php-cli`. Ko poženemo `php -S 0:1234` v nekem direktoriju, lahko iz lupine modema prenašamo datoteke z vgrajenimi programi: `wget http://192.168.8.87:1234/a.out && chmod +x a.out && ./a.out`.
### Prevajanje velikih programov
Za kvantitativno merjenje količine Internetnega prometa mi je zaradi preprostosti najbolj priljubljen program [vnStat](//humdi.net/vnstat/). Brez možnosti generiranja slik, za kar je potrebna še `libgd`, je odvisen je samo od knjižnice `sqlite3`, zato moramo najprej prevesti libsqlite3.
Ker je pri prevajanju za druge arhitekture poleg drugačnih oblik izvršljivih datotek upoštevati tudi obstoj drugačnih oblik knjižnic, imajo verige orodij priložen t. i. sistemski koren, ki vsebuje datoteke, kot naj bi bile na napravi, ki jo programiramo. Sicer prihaja do odstopanj. Broadcomov stbgcc ima namreč veliko nekompatibilnosti knjižnic, zato priporočam statično linkanje vseh binarnih datotek, saj v nasprotnem primeru vsaj meni izvajanje ni delovalo. Za preprečevanje smetenja po sistemskem korenu iz programskega paketa se ponavadi celoten sistemski koren prekopira nekam drugam.
cd
mkdir modem
cd modem
cp -r /opt/toolchains/stbgcc-8.4-0.4/mips-unknown-linux-gnu/sys-root root
`sqlite3` je dostopen na [spletni strani](//www.sqlite.org/download.html).
wget https://www.sqlite.org/2022/sqlite-autoconf-3370200.tar.gz -O/tmp/sqlite.tar.gz
tar -xvf /tmp/sqlite.tar.gz
cd sqlite-autoconf-3370100
./configure --host=mips --prefix=$HOME/modem/root --with-sysroot=$HOME/modem/root CC=mips-linux-gcc LDFLAGS="-static -ldl" CFLAGS=-static
make
make install
`vnstat` je dostopen na [spletni strani](//humdi.net/vnstat/).
wget https://humdi.net/vnstat/vnstat-2.8.tar.gz -O/tmp/vnstat.tar.gz
tar -xvf /tmp/vnstat.tar.gz
cd vnstat-2.8
./configure --host=mips --prefix=$HOME/modem/root CC=mips-linux-gcc LDFLAGS="-static --sysroot=$HOME/modem/root -L$HOME/modem/root/lib -pthread" CFLAGS="-static --sysroot=$HOME/modem/root -I$HOME/root/modem/include" CXXFLAGS="-static --sysroot=$HOME/modem/root -I$HOME/modem/root/include" LIBS=-ldl
make
make install
ONT nima nastavljene ure. Uro moramo nastaviti ob vsakem ponovnem zagonu iz računalnika.
echo "date -s `TZ=UTC date --rfc-3339=seconds`" > /dev/ttyUSB0
Sedaj izvršljivi datoteki `$HOME/root/sbin/vnstatd` in `$HOME/root/bin/vnstat` prenesemo na USB ključek preko omrežja. Na računalniku v direktoriju `$HOME/root` poženemo `php -S 0:1234` in na modemu izvedemo ukaze:
cd /data
mkdir usb
mount /dev/sda usb
cd usb
wget http://192.168.8.87:1234/sbin/vnstatd
wget http://192.168.8.87:1234/bin/vnstat
chmod +x vnstat vnstatd
mkdir vnstat-dir
ln -s /data/usb/vnstat-dir /var/lib/vnstat
./vnstatd --initdb
./vnstat --add --iface eth1
./vnstat --noadd -d &
Za pridobivanje statistika vsakih pet minut iz modema na računalnik lahko uporabimo skript, podoben slednjemu.
vnst=./vnstat
if [ x"$1" = x"html" ]
then
echo ""
echo "<!DOCTYPE html><html lang=en><head><meta charset=UTF-8 /><title>statistika prometa omrežja</title></head><body><pre>"
$vnst --short
echo "</pre><hr><pre>"
$vnst --days
echo "</pre><hr><pre>"
$vnst --fiveminutes
echo "</pre><hr><pre>"
$vnst --hours
echo "</pre><hr><pre>"
$vnst --hoursgraph
echo "</pre><hr><pre>"
$vnst --months
echo "</pre><hr><pre>"
$vnst --top
echo "</pre><hr><pre>"
$vnst --traffic
echo "</pre><hr><pre>"
$vnst --years
echo "</pre></body></html>"
exit
fi
while :
do
$0 html | nc 192.168.8.87 8678
sleep 300
done
Naložimo skript na modem in ga poženemo v ozadju (`./skript.sh`). Na računalniku pa v ozadju poganjamo skript, ki te podatke sprejema.
screen -dmS ont socat TCP-LISTEN:8678,range=192.168.8.1/24,fork,reuseaddr 'SYSTEM:cat > /var/www/html/ont.html'
Sedaj lahko -- v kolikor imamo naložen nek HTTP strežnik na računalniku (`apt install nginx`) -- sprejemamo statistiko modema z obiskom spletne strani http://localhost/ont.html.
<!--
https://tttapa.github.io/Pages/Raspberry-Pi/C++-Development/Dependencies.html
PATH=$PATH:/opt/toolchains/stbgcc-6.3-1.9/bin
sqlite3:
./configure --host=mips --prefix=/root/hax/tsmodem/comp/root --with-sysroot=/root/hax/tsmodem/comp/root CC=mips-linux-gcc LDFLAGS="-static -ldl" CFLAGS=-static
libgd:
wget https://github.com/libgd/libgd/releases/download/gd-2.3.3/libgd-2.3.3.tar.gz
tar -xvf libgd-2.3.3.tar.gz
cd libgd-2.3.3
./configure --host=mips --prefix=$root --with-sysroot=$root CC=mips-linux-gcc LDFLAGS=-static CFLAGS="--sysroot=$root -I$root/include -I$root/usr/include" CPPFLAGS=--sysroot=$root
# mi ni uspelo, includa header fajle za x86_64
vnstat:
./configure --host=mips --prefix=/root/hax/tsmodem/comp/root CC=mips-linux-gcc LDFLAGS="-static --sysroot=/root/hax/tsmodem/comp/root -L/root/hax/tsmodem/comp/root/lib -pthread" CFLAGS="-static --sysroot=/root/hax/tsmodem/comp/root -I/root/hax/tsmodem/comp/root/include" CXXFLAGS="-static --sysroot=/root/hax/tsmodem/comp/root -I/root/hax/tsmodem/comp/root/include" LIBS=-ldl
mkdir /data/usb/vnstat-dir
ln -s /data/usb/vnstat-dir /var/lib/vnstat
./vnstatd --initdb
./vnstat --add --iface eth1
./vnstatd --noadd -d
ura ni nastavljena!
za nastavitev: echo "date -s `TZ=UTC date --rfc-3339=seconds`" > /dev/ttyUSB0
txt statistika:
wget http://t.sijanec.eu/script.sh # tole si priredi in potem naloži iz svojega serverja
chmod +x script.sh
./script.sh &
na serverju, ki bo serviral HTML file po HTTP pa:
screen -dmS ont socat TCP-LISTEN:8678,range=192.168.8.1/24,fork,reuseaddr 'SYSTEM:cat > /var/www/html/ont.html'
# multicat
https://www.videolan.org/projects/multicat.html
apt install libbitstream-dev
cd $root/..
wget https://get.videolan.org/multicat/2.3/multicat-2.3.tar.bz2
tar -xvf multicat-2.3.tar.bz2
cd multicat-2.3
# rabimo še /usr/include/bitstream/ietf/rtp.h - zgolj definicije RTP hearjev, itd., verjetno neodvisne od arhitekture (ups #0 za prihodnost), itak ne rabimo RTP parsanja (še, ups #1 za prihodnost)
PREFIX=$root CC=mips-linux-gcc LDFLAGS="-static -L=$root/lib" CFLAGS="-I$root/usr/include -I$root/include -I/usr/include" make -e # binary je nekih pet megabajtov, hehe
PREFIX=$root CC=mips-linux-gcc LDFLAGS="-static -L=$root/lib" CFLAGS="-I$root/usr/include -I$root/include -I/usr/include" make install -e
php -S 0:1234 # prenesemo na ONT
cd /data/usb && wget http://192.168.8.87:1234/multicat && chmod +x multicat && ./multicat # na ONT
# reži tukaj
./vnstat --remove --force -i br5
./vnstat --remove --force -i bcmsw
./vnstat --remove --force -i gpondef
./vnstat --remove --force -i br0
./vnstat --remove --force -i eth2
./vnstat --remove --force -i br4
./vnstat --remove --force -i br1
./vnstat --remove --force -i eth1.0
./vnstat --remove --force -i ip6tnl0
./vnstat --remove --force -i br6
./vnstat --remove --force -i br2
./vnstat --remove --force -i br7
./vnstat --remove --force -i br3
./vnstat --remove --force -i eth1
./vnstat --remove --force -i eth2.0
vnstat narobe kaže. poskusimo darkstat.
root=/root/hax/tsmodem/comp/root
mkdir -p $root/lib
cd $root/..
wget https://unix4lyfe.org/darkstat/darkstat-3.0.719.tar.bz2
tar -xvf darkstat-3.0.719.tar.bz2 libpcap-1.10.1.tar.gz
# rabimo libpcap
wget https://www.tcpdump.org/release/libpcap-1.10.1.tar.gz
tar -xvf libpcap-1.10.1.tar.gz
cd libpcap-1.10.1
apt install flex bison
./configure --host=mips --prefix=$root CC=mips-linux-gcc LDFLAGS=--sysroot=$root CFLAGS=--sysroot=$root
make
make install
# rabimo zlib
nc -lvp 4444 > $root/lib/libpcap.so
chmod +x $root/lib/libpcap.so
wget https://zlib.net/zlib-1.2.11.tar.gz
tar -xvf zlib-1.2.11.tar.gz
cd $root/../zlib-1.2.11
CC=mips-linux-gcc ./configure --eprefix=$root --libdir=$root/lib --sharedlibdir=$root/lib --includedir=$root/usr/include --prefix=$root
make
make install
# zdaj pa darkstat
cd $root/../darkstat-3.0.719
sed -ie "s/privdrop(.\*)//g" darkstat.c dns.c
./configure --host=mips --prefix=$root --with-pcap=$root CC=mips-linux-gcc LDFLAGS="-static --sysroot=$root" CFLAGS=--sysroot=$root
HOSTCC=gcc HOSTCFLAGS=-I/usr/include make -e
make install
# skopiraj $root/sbin/darkstat (statično linkan, 6 megabajtov!) na /data/usb/darkstat
cd /data/usb
chmod +x darkstat
mkdir darkstat-dir
chmod 0777 darkstat-dir
./darkstat -i gpon0 --no-dns -l 0.0.0.0/0 --chroot /data/usb/darkstat-dir --user nobody --daylog daylog --import db --export db --no-daemon --base darkstat --verbose
# pid opcija še vedno uporablja getpwnam, tako da ne dodaj argumenta --pidfile
http://192.168.8.1/darkstat
location /darkstat {
return 308 /darkstat/;
}
location /darkstat/ {
proxy_pass http://192.168.8.1:667;
}
# strace
cd $root/..
wget https://strace.io/files/5.15/strace-5.15.tar.xz
tar -xvf strace-5.15.tar.xz
cd strace-5.15.tar.xz
./configure --host=mips --prefix=$root CC=mips-linux-gcc LDFLAGS="-static --sysroot=$root" CFLAGS=--sysroot=$root
# fak ne dela
-->