luci-0.11: Merge r9624 - r9626
[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/network.sh
7
8 #Exit if this script is already running
9 pid="$(pidof ff_olsr_test_gw.sh)"
10 if [ ${#pid} -gt 5 ]; then
11         logger -t gwcheck "Gateway check script is already running, exit now"
12         exit 1
13 fi
14
15 #check if dyngw_plain is installed and enabled, else exit
16 dyngwplainlib=`uci show olsrd |grep dyn_gw_plain |awk {' FS="."; print $1"."$2 '}`
17 if [ -n "$dyngwplainlib" ]; then
18         if [ "$(uci -q get $dyngwplainlib.ignore)" == 1 ]; then
19                 exit 1
20         fi
21 else
22         exit 1
23 fi
24
25 #Exit if this script is already running
26 pid="$(pidof ff_olsr_test_gw.sh)"
27 if [ ${#pid} -gt 5 ]; then
28         logger -p debug -t gwcheck "Gateway check script is already running, exit now"
29         exit 1
30 fi
31
32 # exit if there is no defaultroute with metric=0 in main or gw-check table.
33 defroutemain="$(ip r s |grep default |grep -v metric)"
34 defroutegwcheck="$(ip r s t gw-check |grep default |grep -v metric)"
35 if [ -z "$defroutegwcheck" -a -z "$defroutemain" ]; then
36         exit 1
37 fi
38
39 # get and shuffle list of testservers
40 testserver="$(uci -q get freifunk-gwcheck.hosts.host)"
41 [ -z "$testserver" ] && echo "No testservers found, exit" && exit
42
43 testserver="$(for t in $testserver; do echo $t; done | awk 'BEGIN {
44         srand();
45 }
46 {
47         l[NR] = $0;
48 }
49
50 END {
51         for (i = 1; i <= NR; i++) {
52                 n = int(rand() * (NR - i + 1)) + i;
53                 print l[n];
54                 l[n] = l[i];
55         }
56 }')"
57
58 check_internet() {
59         for t in $testserver; do
60                 local test
61                 test=$(wget -q http://$t/conntest.html -O -| grep "Internet_works")
62                 if [ "$test" == "Internet_works" ]; then
63                         echo 0
64                         break
65                 else
66                         logger -p debug -t gw-check "Could not fetch http://$t/conntest.html"
67                 fi
68         done
69 }
70
71 resolve() {
72         echo "$(nslookup $1 2>/dev/null |grep 'Address' |grep -v '127.0.0.1' |awk '{ print $3 }')"
73 }
74
75 get_dnsservers() {
76         # this gets all dns servers for the wan interface. If ubus is not present (like on older
77         # openwrt versions before Attitude fallback to get these from /var/state/network.
78
79         dns=""
80         if [ -x /bin/ubus ]; then
81                 network_get_dnsserver dns wan
82         else
83                 dns="$(grep network.wan.resolv_dns /var/state/network | cut -d "=" -f 2)"
84         fi
85 }
86
87 iw=$(check_internet)
88
89
90 if [ "$iw" == 0 ]; then
91         # check if we have a seperate routing table for our tests.
92         # If yes, move defaultroute to normal table and delete table gw-check
93         # Also delete ip rules to use table gw-check for our testhosts and wan dns servers
94         
95         if [ -n "$defroutegwcheck" ]; then
96                 ip r a $defroutegwcheck
97                 ip r d $defroutegwcheck t gw-check
98                 for host in $testserver; do
99                         ips="$(resolve $host)"
100                         for ip in $ips; do
101                                 [ -n "$(ip ru s | grep "to $ip lookup gw-check")" ] && ip rule del to $ip table gw-check
102                         done
103                 done
104
105                 get_dnsservers
106                 for d in $dns; do
107                         [ -n "$(ip ru s | grep "to $d lookup gw-check")" ] && ip rule del to $d table gw-check
108                 done
109
110                 #ip r d default via 127.0.0.1 metric 100000
111                 logger -t gw-check "Internet is available again, restoring default route ( $defroutegwcheck)"
112         fi
113
114 else
115         # Check failed. If we have a defaultroute with metric=0 and it is already in table gw-check then do nothing.
116         # If there is a defaultroute with metric=0 then remove it from the main routing table and add to table gw-check.
117         # Also setup ip rules to use table gw-check for our testhosts and wan dns servers
118
119         if [ -z "$(ip ru s | grep gw-check)" -a -n "$defroutemain" ]; then
120                 ip r a $defroutemain table gw-check
121                 ip r d $defroutemain
122         fi
123         for host in $testserver; do
124                 ips="$(resolve $host)"
125                 for ip in $ips; do
126                         [ -z "$(ip ru s | grep "to $ip lookup gw-check")" ] && ip rule add to $ip table gw-check
127                 done
128         done
129         get_dnsservers
130         for d in $dns; do
131                 [ -z "$(ip ru s | grep "to $d lookup gw-check")" ] && ip rule add to $d table gw-check
132         done
133         #ip r a default via 127.0.0.1 metric 100000
134         logger -t gw-check "Internet is not available, deactivating the default route ( $defroutemain)"
135 fi