Ecco un piccolo script per effettuare i check delle reti LAN e riavviare, in caso, o le interfacce o il router stesso.
Premessa
Il router DGND4000 della Netgear deve preventivamente essere modificato con la mod di Amod, le istruzioni per l'installazione della mod le trovate qui: http://alfie.altervista.org/amod4000/
La directory con le config è scrivibile senza rimontare la root in rw:
mtd:xxx on /config/xxx type jffs2 (rw,relatime)
mtd:xxx 2048 464 1584 23% /config/xxx
Le varie config e gli script che creeremo saranno sotto la dir /config/xxx/amod
Lo script
Creare lo script nella dir qua sotto con le seguenti permission:
/config/xxx/amod # ls -l check_net.sh
-rwxr-xr-x 1 root root 2551 Jun 18 10:19 check_net.sh
Lo script prende in input la network con l'ip di partenza, il range e le interfacce coinvolte nel down up in caso di ping failed.
/usr/etc/amod/conf/check_net.sh 192.168.0.2 5 eth0,eth1,eth2,eth3,wl0
Indirizzo ip di partenza
Range ip
Interfacce di rete
Nell'esempio qua sopra se non risponde nulla gli ip checcati saranno il 192.168.0.2, 192.168.0.3, 192.168.0.4, 192.168.0.5, 192.168.0.6 prima di effettuare il down up delle interfacce eth0,eth1,eth2,eth3 e wl0 o il reset del router (dipende se è stato raggiunto il numero massimo di retry del down/up).
Nel file /tmp/check_net_identificativonetwork.log vengono messe le operazioni svolte, il file reboot invece serve come counter dei failed prima di riavviare completamente il router.
La funzione is_alive_ping effettua un ping all'ip in input e restituisce 0 quando l'ip non risponde, nel main viene fatto un ciclo del range di ip dato in input e non appena un ip risponde esce dallo script con esito positivo e cancella l'eventuale file di retry, altrimenti se nessun ip del range ha risposto controlla prima se esiste un file di retry, lo legge, verifica se è stato raggiunto il numero massimo di retry (variabile retry_reboot), se è stato raggiunto il numero massimo di retry rebootta il router, altrimenti se non esiste crea un nuovo file di retry o incrementa il contenuto dello stesso. In seguito effettua un ciclo di down di tutte le interfacce passate come parametro $3 ed esce:
#!/bin/sh
is_alive_ping()
{
ping -c 1 $1 > /dev/null
[ $? -ne 0 ] && return 0
}
pong=0
ip=$(echo $1 | cut -d"." -f4-)
range=$2
network=$(echo $1 | cut -d"." -f1-3)
ipstop=$(($ip + $range))
filereboot=/tmp/check_net_reboot_$network.txt
filelog=/tmp/check_net_$network.log
retry_reboot=3
IN=$3
interfaces=$(echo $IN | tr "," "\n")
echo "--------------------------------------------------------" >> $filelog
while [ $ip -ne $ipstop ] && [ $pong -eq 0 ] ; do
is_alive_ping "$network.$ip"
pong=$?
ip=$(($ip+1))
done
if [ $pong -eq 0 ]
then
echo "$(date) Rete "$network" non risponde" >> $filelog
echo "Rete "$network" non risponde"
if [[ -f "$filereboot" ]]
then
echo "$(date) Esiste il file per reboot: $filereboot " >> $filelog
echo "$(date) Eseguo verifica se superato il numero dei retry ($retry_reboot)" >> $filelog
echo "Esiste il file per reboot: $filereboot "
echo "Eseguo verifica se superato il numero dei retry ($retry_reboot)"
num_retry_reboot=$(cat $filereboot)
echo "$(date) Numero retry eseguiti $num_retry_reboot" >> $filelog
echo "Numero retry eseguiti $num_retry_reboot"
if [ $num_retry_reboot -lt $retry_reboot ]
then
num_retry_reboot=$(($num_retry_reboot+1))
echo "$(date) Non e stato superato il numero max di retry, aggiorno num retry:$num_retry_reboot" >> $filelog
echo "Non e stato superato il numero max di retry, aggiorno num retry:$num_retry_reboot"
echo $num_retry_reboot > $filereboot
else
echo "$(date) Numero retry superato!!! Riavvio il router" >> $filelog
echo "Numero retry superato!!! Riavvio il router"
reboot -f
fi
else
echo "$(date) Non esiste il file per reboot, lo creo: $filereboot " >> $filelog
echo "Non esiste il file per reboot, lo creo: $filereboot "
echo "1" > $filereboot
fi
for interface in $interfaces
do
echo "$(date) Faccio down dell'interfaccia $interface" >> $filelog
echo "Faccio down dell'interfaccia $interface"
ifconfig $interface down
sleep 20
echo "$(date) Faccio up dell'interfaccia $interface" >> $filelog
echo "Faccio up dell'interfaccia $interface"
ifconfig $interface up
done
else
echo "$(date) Rete "$network" risponde" >> $filelog
echo "Rete "$network" risponde"
if [[ -f "$filereboot" ]]
then
echo "$(date) Esiste un file di retry, lo cancello" >> $filelog
echo "Esiste un file di retry, lo cancello"
rm -rf $filereboot
fi
fi
Inserimento in crontab
Controllare che esista e abbia queste permission il file rcS1.user usato per l'esecuzione degli script di boot del router:
/config/xxx/amod # ls -latr rcS1.user
-rwxr-xr-x 1 root root 259 Jun 18 09:23 rcS1.user
Bisogna aggiungere questa riga di codice al file di cui sopra, in modo che venga inserito lo script nel crontab amod, questo script verrà eseguito ogni 5 minuti, in particolare queste 2 entry controllano 2 reti (la 192.168.0 interna e la 192.168.1 che è la rete che nel mio caso va verso il modem telecom):
# cat /etc/amod/conf/rcS1.user
#!/bin/sh
...
...
/etc/amod/bin/cron add "*/5 * * * * /usr/etc/amod/conf/check_net.sh 192.168.0.2 5 eth0,eth1,eth2,eth3,wl0"
/etc/amod/bin/cron add "*/5 * * * * /usr/etc/amod/conf/check_net.sh 192.168.1.1 1 eth4"
Controllare se dopo il reboot del router ci sono le schedulazioni corrette:
# cat /etc/crontabs/root
..................
*/5 * * * * /usr/etc/amod/conf/check_net.sh 192.168.0.2 5 eth0,eth1,eth2,eth3,wl0
*/5 * * * * /usr/etc/amod/conf/check_net.sh 192.168.1.1 1 eth4
.................