Merge pull request #229 from cholin/bug/gwcheck_jshn
[project/luci.git] / contrib / package / freifunk-gwcheck / files / usr / sbin / ff_olsr_test_gw.sh
1 #!/bin/sh
2 # Copyright 2013 Manuel Munz <freifunk at somakoma dot de>
3 # Licensed under the GNU General Public License (GPL) v3
4 # This script monitors the local internet gateway
5
6 . /lib/functions.sh
7 . /lib/functions/network.sh
8 . /usr/share/libubox/jshn.sh
9
10 # exit if dyngw_plain is not enabled or RtTable is not (254 or unset)
11 config_load olsrd
12
13 check_dyngw_plain()
14 {
15         local cfg="$1"
16         config_get library "$cfg" library
17         if [ "${library#olsrd_dyn_gw_plain}" != "$library" ]; then
18                 config_get ignore "$cfg" ignore
19                 config_get RtTable "$cfg" RtTable
20                 if [ "$ignore" != "1" ] && [ -z "$RtTable" -o "$RtTable" = "254" ]; then
21                         exit=0
22                 fi
23         fi
24 }
25
26 exit=1
27 config_foreach check_dyngw_plain LoadPlugin
28 [ "$exit" = "1" ] && exit 1
29
30 #Exit if this script is already running
31 pid="$(pidof ff_olsr_test_gw.sh)"
32 if [ ${#pid} -gt 5 ]; then
33         logger -p debug -t gwcheck "Gateway check script is already running, exit now"
34         exit 1
35 fi
36
37 # exit if there is no defaultroute with metric=0 in main or gw-check table.
38 defroutemain="$(ip route show |grep default |grep -v metric)"
39 defroutegwcheck="$(ip route show table gw-check |grep default |grep -v metric)"
40 if [ -z "$defroutegwcheck" -a -z "$defroutemain" ]; then
41         exit 1
42 fi
43
44 # get and shuffle list of testservers
45 testserver="$(uci -q get freifunk-gwcheck.hosts.host)"
46 [ -z "$testserver" ] && echo "No testservers found, exit" && exit
47
48 testserver="$(for t in $testserver; do echo $t; done | awk 'BEGIN {
49         srand();
50 }
51 {
52         l[NR] = $0;
53 }
54
55 END {
56         for (i = 1; i <= NR; i++) {
57                 n = int(rand() * (NR - i + 1)) + i;
58                 print l[n];
59                 l[n] = l[i];
60         }
61 }')"
62
63 check_internet() {
64         for t in $testserver; do
65                 local test
66                 test=$(wget -q http://$t/conntest.html -O -| grep "Internet_works")
67                 if [ "$test" == "Internet_works" ]; then
68                         echo 0
69                         break
70                 else
71                         logger -p debug -t gw-check "Could not fetch http://$t/conntest.html"
72                 fi
73         done
74 }
75
76 resolve() {
77         echo "$(nslookup $1 2>/dev/null |grep 'Address' |grep -v '127.0.0.1' |awk '{ print $3 }')"
78 }
79
80 get_dnsservers() {
81         # this gets all dns servers for the interface which has the default route
82
83         dns=""
84         if [ ! -x /bin/ubus ]; then
85                 # ubus not present (versions before Attitude): fallback to get these from /var/state/network.
86                 # We always assume that wan is the default route interface here
87                 dns="$(grep network.wan.resolv_dns /var/state/network | cut -d "=" -f 2)"
88         else
89                 network_find_wan wan
90                 network_get_dnsserver dns $wan
91         fi
92 }
93
94 iw=$(check_internet)
95
96 if [ "$iw" == 0 ]; then
97         # Internet available again, restore default route and remove ip rules
98         if [ -n "$defroutegwcheck" ]; then
99                 ip route add $defroutegwcheck
100                 ip route del $defroutegwcheck table gw-check
101                 for host in $testserver; do
102                         ips="$(resolve $host)"
103                         for ip in $ips; do
104                                 [ -n "$(ip rule show | grep "to $ip lookup gw-check")" ] && ip rule del to $ip table gw-check
105                         done
106                 done
107                 get_dnsservers
108                 for d in $dns; do
109                         [ -n "$(ip rule show | grep "to $d lookup gw-check")" ] && ip rule del to $d table gw-check
110                 done
111                 logger -p err -t gw-check "Internet is available again, default route restored ( $defroutegwcheck)"
112         fi
113
114 else
115         # Check failed. Move default route to table gw-check and setup ip rules.
116         if [ -z "$(ip rule show | grep gw-check)" -a -n "$defroutemain" ]; then
117                 ip route add $defroutemain table gw-check
118                 ip route del $defroutemain
119                 logger -p err -t gw-check "Internet is not available, default route deactivated ( $defroutemain)"
120         fi
121         for host in $testserver; do
122                 ips="$(resolve $host)"
123                 for ip in $ips; do
124                         [ -z "$(ip rule show | grep "to $ip lookup gw-check")" ] && ip rule add to $ip table gw-check
125                 done
126         done
127         get_dnsservers
128         for d in $dns; do
129                 [ -z "$(ip rule show | grep "to $d lookup gw-check")" ] && ip rule add to $d table gw-check
130         done
131         logger -p err -t gw-check "Check your internet connection!"
132 fi