kako uporabiti ts ont kot merilnik prenosa podatkov :: anton luka šijanec

kako uporabiti ts ont kot merilnik prenosa podatkov

spisal 30. decembra 2021, dopolnil 27. avgusta 2022.
dnevnik sprememb

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), 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, ki se ga da 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 objavljene.

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 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 na tiskanem vezju 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, 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 s pobitjem procesov 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, fizično ali programsko komponento, ki, če ne dobi ustreznega signala ustreznem časovnem obdobju, ponovno zažene celoten sistem, v upanju, da se bo delovanje povrnilo v prvotno stanje. 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 nepotrebnih procesov (HTTP, SMB, SNMP, DHCP, DNS, NTP, ...).

Nastavitev okolja za prevajanje

Sedaj imamo polno izvajanje kode kot root na sistemu, na napravi pa hočemo poganjati neke poljubne programe. V mojem primeru je to merilec prometa na omrežju, ki je spisan v programskem jeziku C.

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 (angl. cross-compilation). 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. V primeru, da programje izgine iz obličja Interneta, so tukaj varnostne kopije.

Č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 z i386 kompatibilen računalnik, pa si lahko deb paket naloži tukaj.

V nasprotnem primeru pa preprosto prevedemo izvodno kodo prevajalnika sami.

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. Seveda preko enega izmed dveh Ethernet priključkov.

ip addr add dev eth99 192.168.8.87/24

Za prenos datotek je koristen v PHP vgrajen preprost HTTP strežnik 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. 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 treba 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 glede 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.3-0.4/mips-unknown-linux-gnu/sys-root root

sqlite3 je dostopen na spletni strani.

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.

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/modem/root/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/modem/root/sbin/vnstatd in $HOME/modem/root/bin/vnstat prenesemo na USB ključek preko omrežja. Na računalniku v direktoriju $HOME/modem/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
mkdir -p /var/lib #
ln -s /data/usb/vnstat-dir /var/lib/vnstat #
./vnstatd --initdb
./vnstat --add --iface eth1
./vnstatd --noadd -d & #

Sedaj daemon za shranjevanje podatkov teče. Za zaganjanje merilnika po ponovnem zagonu modema je treba zagnati le tiste ukaze, ki so označeni z #, da ostane ista podatkovna zbirka s preteklimi meritvami. Za pridobivanje statistik 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&zcaron;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 in jih vedno znova zapiše v datoteko:

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.

Moja mrežna statistika, vzpostavljena prav tako, kot je opisano v tem članku, je dostopna na http://tranzistor.sijanec.eu/ont.html.

Kasneje sem za predstavitev tegale početja prevedel še knjižnice libpng, libfreetype in libgd in vnstat prevedel s podporo za generiranje slikovnih diagramov, zato lahko mrežno statistiko odslej spremljam tudi z generiranimi PNG slikami.