Escaneig de senyal des de la teulada amb iw dev $wlan station dump i OpenWrt

Quan estem a la teulada veient quina podria ser la millor posició on deixar l’antena, ens fixarem en paràmetres de qualitat de la senyal wifi gairebé en temps real (refresc cada segon). Necessitaríem poder connectar-nos a l’antenna per ssh.

Connectar-se a l’antenna per ssh

Opció amb DHCP (IPv4)

Normalment, aquestes antenes permeten connectar-se mitjançant una assignació automàtica (DHCP client), i assumim que ho volem fer per IPv4

Si hi ha èxit i veiem la porta predeterminada (default gateway) trobarem el node al que connectar-nos

Normalment és la primera linia de la comanda de terminal ip route show (o abreviat: ip r)

$ ip r
default via 192.168.99.1 dev enx000aaaaaaaaa proto dhcp src 192.168.99.111 metric 100 
192.168.99.0/24 dev enx000aaaaaaaaa proto kernel scope link src 192.168.99.111 metric 100 

en aquest cas d’exemple, la default gateway seria 192.168.99.1 (podria ser que el teu resultat tingui més línies, només t’has de fixar en la primera i en el valor després de “default via”)

Probablement voldríem fer doncs:

ssh root@192.168.99.1

Opció amb IPv6

OpenWrt funciona amb IPv6 per defecte, tots els enllaços IPv6 tenen una adreça assignada automàticament de link local

Primer necessitaríem saber a quina interfície volem esbrinar la ip link local de l’altre dispositiu, faríem ip link

$ ip link
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN mode DEFAULT group default qlen 1000
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
2: enx000aaaaaaaaa: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc fq_codel state UP mode DEFAULT group default qlen 1000
    link/ether aa:bb:aa:bb:aa:bb brd ff:ff:ff:ff:ff:ff

(en el teu equip podrien sortir més línies), i doncs, volem l’interfície enx000aaaaaaaaa, si fem un ipv6 link local, ens respondran 2 adreces, la que té més latència (més lluny), és a la que ens voldríem connectar (fe80::f6a4:54ff:bbbb:1111%enx000aaaaaaaa en aquest cas)

$ ping6 ff02::1%enx000aaaaaaaa
PING ff02::1%enx000aaaaaaaa(ff02::1%enx000aaaaaaaa) 56 data bytes
64 bytes from fe80::20e:c6ff:aaaa:000%enx000aaaaaaaa: icmp_seq=1 ttl=64 time=0.035 ms
64 bytes from fe80::f6a4:54ff:bbbb:1111%enx000aaaaaaaa: icmp_seq=1 ttl=64 time=0.714 ms
64 bytes from fe80::20e:c6ff:aaaa:000%enx000aaaaaaaa: icmp_seq=2 ttl=64 time=0.045 ms
64 bytes from fe80::f6a4:54ff:bbbb:1111%enx000aaaaaaaa: icmp_seq=2 ttl=64 time=0.712 ms

Probablement voldríem fer doncs:

ssh root@fe80::f6a4:54ff:bbbb:1111%enx000aaaaaaaa

Un cop estem connectats per ssh

Esbrinar interfície wifi de l’antenna

Un cop connectats per ssh, i abans de res, quines són les interfícies actives de wifi?

# iw dev
phy#0
	Interface wif1
		ifindex 8
		wdev 0x3
		addr aa:aa:aa:aa:aa:aa
		ssid guifi.net/masked
		type IBSS
		channel masked
		txpower masked
		multicast TXQ:
			qsz-byt	qsz-pkt	flows	drops	marks	overlmt	hashcol	tx-bytes	tx-packets
			0	0	925712	0	0	0	4	104808114		925719
	Interface wif0
		ifindex 7
		wdev 0x2
		addr bb:bb:bb:bb:bb:bb
		type mesh point
		channel masked
		txpower masked
		multicast TXQ:
			qsz-byt	qsz-pkt	flows	drops	marks	overlmt	hashcol	tx-bytes	tx-packets
			0	0	927231	0	0	0	0	108139126		927243

Apliquem un filtre per resumir millor les dades

# iw dev | grep Interface
	Interface wif1
	Interface wif0

Ok, llavors tenim, en aquest cas les interfícies wif0 i wif1. En aquesta antena, com a curiositat/offtopic, té un protocol mesh per mode mesh antic i retrocompatible d’adhoc/ibss i el nou 802.11s (que li diu el meshpoint).

Comanda bàsica

Aquesta és la comanda amb totes les dades que dona l’station dump, que són masses.

Nota: assumim que volem mesurar wif0, si volem mesurar wif1 faríem wlan=wif1, o com es digui la vostra interfície wifi. (veure apèndix 1 per més info)

wlan=wif0; while true; do clear; iw dev $wlan station dump; sleep 1; done

dona un resultat tal com el següent

Nota: enmascarats els BSSID de les dos estacions trobades com cc:cc:cc:cc:cc:cc i dd:dd:dd:dd:dd:dd respectivament

Station cc:cc:cc:cc:cc:cc (on wif0)
	inactive time:	0 ms
	rx bytes:	737542432
	rx packets:	6329743
	tx bytes:	92005531
	tx packets:	293230
	tx retries:	554224
	tx failed:	44349
	rx drop misc:	49026
	signal:  	-64 [-69, -66] dBm
	signal avg:	-65 [-69, -67] dBm
	Toffset:	18446743741654842260 us
	tx bitrate:	108.0 MBit/s MCS 11 40MHz
	rx bitrate:	120.0 MBit/s MCS 11 40MHz short GI
	rx duration:	0 us
	last ack signal:27 dBm
	expected throughput:	40.191Mbps
	mesh llid:	36894
	mesh plid:	52586
	mesh plink:	ESTAB
	mesh local PS mode:	ACTIVE
	mesh peer PS mode:	ACTIVE
	mesh non-peer PS mode:	ACTIVE
	authorized:	yes
	authenticated:	yes
	associated:	yes
	preamble:	long
	WMM/WME:	yes
	MFP:		no
	TDLS peer:	no
	DTIM period:	2
	beacon interval:100
	short slot time:yes
	connected time:	436439 seconds
Station dd:dd:dd:dd:dd:dd (on wif0)
	inactive time:	2540 ms
	rx bytes:	386158
	rx packets:	5793
	tx bytes:	723
	tx packets:	10
	tx retries:	34
	tx failed:	3
	rx drop misc:	1
	signal:  	-82 [-83, -86] dBm
	signal avg:	-82 [-84, -85] dBm
	Toffset:	287805149634 us
	tx bitrate:	6.5 MBit/s MCS 0
	rx bitrate:	6.5 MBit/s MCS 0
	rx duration:	0 us
	expected throughput:	2.197Mbps
	mesh llid:	9673
	mesh plid:	12714
	mesh plink:	ESTAB
	mesh local PS mode:	ACTIVE
	mesh peer PS mode:	ACTIVE
	mesh non-peer PS mode:	ACTIVE
	authorized:	yes
	authenticated:	yes
	associated:	yes
	preamble:	long
	WMM/WME:	yes
	MFP:		no
	TDLS peer:	no
	DTIM period:	2
	beacon interval:100
	short slot time:yes
	connected time:	14388 seconds

Es confirma que són moltes dades per ser visibles en pantalla, i canvien cada segon. Especialment si ens estem connectant a diverses estacions i volem veure tota la informació més agregada, i saber a quina estació/node seria més adient connectar-se.

Comanda amb filtre

Es proposa llavors una comanda modificada que aplica uns filtres (veure apèndix 2 per més info):

wlan=wif0; while true; do clear; iw dev $wlan station dump | grep -iE 'station|signal|bitrate|throughput|inactive time'; sleep 1; done

i aquest és el resultat

Station cc:cc:cc:cc:cc:cc (on wif0)
	inactive time:	0 ms
	signal:  	-66 [-70, -69] dBm
	signal avg:	-66 [-69, -69] dBm
	tx bitrate:	81.0 MBit/s MCS 10 40MHz
	rx bitrate:	90.0 MBit/s MCS 10 40MHz short GI
	last ack signal:27 dBm
	expected throughput:	35.705Mbps
Station dd:dd:dd:dd:dd:dd (on wif0)
	inactive time:	990 ms
	signal:  	-81 [-85, -84] dBm
	signal avg:	-81 [-84, -85] dBm
	tx bitrate:	6.5 MBit/s MCS 0
	rx bitrate:	6.5 MBit/s MCS 0

Amb aquestes dades tenim diferent informació:

  • inactive time: l’última vegada que es va poder contactar l’altre antena. Per exemple si girem massa i veiem que creixen els milisegons vol dir que estem perdent connectivitat amb aquella antena, és a dir, que ens allunyem massa; i passat un temps desapareixerà
  • signal / signal avg: què tal és la senyal (millor si és més gran que -75 dB)
  • tx bitrate / rx bitrate: què tal és la transferència de dades en Mbit i en MCS (més gran, millor)
  • last ack signal: aquest no sé, s’ha colat amb el filtre de signal

Apèndix 1: el bucle while

No tens per què saber-ho, però si tens curiositat de quina comanda estàs executant, és un conjunt d’instruccions d’ash.

La comanda s’escriu en una línia per facilitar el copypaste i l’execució ràpida, desplegada i amb comentaris (els comentaris comencen amb el caràcter #), és:

# asigna variable wlan a valor wif0
wlan=wif0
# bucle que no para de fer voltes (perquè sempre és igual a true)
#   més informació general https://ca.wikipedia.org/wiki/Bucle_(programaci%C3%B3)
#   més informació específica https://manpages.debian.org/bookworm/dash/dash.1.en.html#Flow-Control_Constructs_%E2%80%93_if,_while,_for,_case
while true; do
    # neteja pantalla
    clear
    # aplica la comanda que volem fer
    iw dev $wlan station dump
    # espera un segon, si no esperés un segon ho faria tot lo ràpid que pugués la CPU i l'estressaria
    sleep 1
# avisem que és el final del bloc while
done

Apèndix 2: el filtre o expressió regular grep

Utilitzem grep per filtrar el contingut que ens arriba abans (com si fos una tuberia, el pipe |)

| grep -iE 'station|signal|bitrate|throughput|inactive time'

Podem mirar les opcions a man grep si tenim un sistema compatible unix

L’opció -i fa case insensitive és a dir, que considera com a resultats vàlids majúscules o minúscules

L’opció -E ens permet habilitar les expressions regulars més complexes, en aquest cas, simplement estem fent servir | com si fos un OR (suma lògica o unió, OR binària), si això o això o això funciona, mostra-ho per pantalla, podem afegir o treure més o menys elements segons ens convingui.