Skip to content →

Monitor and toggle network interface on linux

So the wireless driver for TP-Link TL-WN725N I wrote about earlier is a bit prone to dropping the connection every now and then. To mitigate this problem and keep the wireless connection up I wrote a bash script which is run by root’s cron every 5 minutes.


Cron

Use crontab -e to add a cron job

pi@raspberrypi ~ $ sudo crontab -e

Then just place the entry at the bottom, save and exit. (Nano: ctrl + x, then y. Vi(m): :w)

*/5 * * * * /home/pi/src/netmon.sh

If you want to see the output it’s recommended to pipe it to a file.

*/5 * * * * bash /home/pi/src/netmon.sh >/home/pi/src/netmon.log 2>&1

netmon.sh

You can change the interface to check by editing the INTERFACE variable, see highlighted row below. Requires root privileges as it resets the interface.

#!/bin/bash
#netmon.sh

#Config
INTERFACE="wlan0"

#Commands
ROUTE=`which route`
AWK=`which awk`
HEAD=`which head`
TAIL=`which tail`
IFCONFIG=`which ifconfig`
IP=`which ip`
PING=`which ping`
SLEEP=`which sleep`

#ifup and ifdown are not normally in the cron's environment so we specify the paths here
IFUP="/sbin/ifup"
IFDOWN="/sbin/ifdown"

#Config (auto)
GATEWAY=`$ROUTE | $AWK {'print $2'} | $HEAD -n 3 | $TAIL -n 1`
INTERFACEIP=$($IP addr show $INTERFACE | $AWK '/inet / {print $2}' | cut -d/ -f 1)

function valid_ip() {
    local  ip=$1
    local  stat=1

    if [[ $ip =~ ^[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}$ ]]; then
        OIFS=$IFS
        IFS='.'
        ip=($ip)
        IFS=$OIFS
        [[ ${ip[0]} -le 255 && ${ip[1]} -le 255 \
            && ${ip[2]} -le 255 && ${ip[3]} -le 255 ]]
        stat=$?
    fi
    return $stat
}

function ping_ip() {
    $PING $1 -c 4

    return $?
}

function toggle_network_connection() {
    #Always set network down first
    `$IFDOWN $1`

    #Sleep 5 seconds before bringing it up
    $SLEEP 5

    #Bring network up
    `$IFUP $1`

    return $?
}

if [[ ! -z "$INTERFACEIP" ]]; then
    if valid_ip $INTERFACEIP; then
            echo "Interface up with IP $INTERFACEIP"
    else
        if ping_ip $GATEWAY; then
            echo "Network is having issues, gateway $GATEWAY reachable on at least one interface"
            toggle_network_connection $INTERFACE
            RESET=$?
        else
            echo "Network connection is down! Gateway unreachable. Attempting reconnection."
            toggle_network_connection $INTERFACE
            RESET=$?
        fi
    fi
else
    echo "Interface has no ip address. Toggling interface."
    toggle_network_connection $INTERFACE
    RESET=$?
fi

if [[ ! -z "$RESET" ]]; then
    if [[ $RESET -eq 0 ]]; then
        echo "Interface was reset successfully"
    else
        echo "Network connection could not be reset. Reboot recommended."
    fi
else
    echo "No problems with interface $INTERFACE was detected."
fi

Sample output

Interface up:

pi@raspberrypi ~ $ sudo bash netmon.sh
Network up with IP 192.168.10.17
No problems with interface wlan0 was detected.

Interface down:

pi@raspberrypi ~ $ sudo bash netmon.sh
Network has no ip address. Toggling interface.
/sbin/ifdown: interface wlan0 not configured
Network connection was reset successfully

Published in Bash Code Linux

Comments

Leave a Reply

Your email address will not be published.

This site uses Akismet to reduce spam. Learn how your comment data is processed.