0162ed9c607a54fd3108abe8232d1cdada8d9a00
[librecmc/librecmc-fossil.git] /
1 #!/bin/ash
2 export LC_ALL=en_US.UTF-8
3
4 # TODO
5 # * dns und gateway vom dhcp-server übernehmen, erst setzen, wenn ip erhalten
6
7 # vars
8
9 remoteaddresses="{{#peerings}}{{ip}} {{/peerings}}{{#missioncontrol}}{{ip}} {{/missioncontrol}}"
10
11 orggatewayfile="/tmp/cjdns_org_gw"
12
13 network_profile="$(cat /etc/enigmabox/network-profile)"
14 [[ "$network_profile" = "alix" ]] && clearnet_interface="eth0"
15 [[ "$network_profile" = "apu" ]] && clearnet_interface="eth2"
16 [[ "$network_profile" = "raspi" ]] && clearnet_interface="eth1"
17
18 ping="ping -c 5 -W 5"
19 cjdns_request_tries="/tmp/cjdns_request_tries"
20 netstat_file="/tmp/netstat"
21 pidfile="/tmp/setup-cjdns-networking.pid"
22 opmode="{{wlan_opmode}}"
23 ssid="{{wlan_ssid}}"
24 wep_pass="{{wlan_pass}}"
25 security="{{wlan_security}}"
26 dynamic_output="/tmp/dynamic_output"
27
28 {{#if_internet_gateway}}
29 request_internet="yes"
30 {{/if_internet_gateway}}
31
32 {{^if_internet_gateway}}
33 request_internet="no"
34 {{/if_internet_gateway}}
35
36
37
38 # check if its already running
39 if [[ "$1" != "startwifi" ]]; then
40     kill -0 $(cat "$pidfile" 2> /dev/null) 2> /dev/null
41     if [[ "$?" == "0" ]]; then
42         echo "script is already running"
43         exit 0
44     fi
45
46     echo $$ > "$pidfile"
47 fi
48
49
50
51 # functions
52
53 e() {
54     echo 1>&2
55     echo 1>&2
56     echo "$1" 1>&2
57 }
58
59 startwifi() {
60     echo "please wait, configuring system..." > "$dynamic_output"
61     /usr/sbin/cfengine-apply &> /dev/null
62     echo "done" > "$dynamic_output"
63
64     /usr/sbin/setup-cjdns-networking &> "$dynamic_output"
65
66     exit 0 #the script should end here
67 }
68
69 dhcp() {
70     ifconfig "$clearnet_interface" up
71
72     if [[ $( route -n | grep ^0.0.0.0 | wc -l ) -eq 0 ]]; then
73         e "dhcp request $clearnet_interface"
74         udhcpc -i "$clearnet_interface" --now
75     fi
76 }
77
78 start_wpa() {
79     e "start WPA session"
80
81     ifconfig wlan0 down
82     killall wpa_supplicant
83
84     # make sure wpa_supplicant is absent
85     rm "/var/run/wpa_supplicant/wlan0" 2> /dev/null
86
87     sleep 2
88
89     ifconfig wlan0 up
90     wpa_supplicant -i wlan0 -D wext -c /etc/wpa_supplicant/wpa_supplicant.conf -B
91
92     sleep 2
93 }
94
95 start_wep() {
96 {{#if_wlan_pass}}
97     e "start WEP session"
98     ifconfig wlan0 up
99     iwconfig wlan0 essid "$ssid"
100     iwconfig wlan0 key "d:0:$wep_pass"
101 {{/if_wlan_pass}}
102 {{^if_wlan_pass}}
103     e "connecting to AP"
104     ifconfig wlan0 up
105     iwconfig wlan0 essid "$ssid"
106 {{/if_wlan_pass}}
107 }
108
109 request_cjdns_internet() {
110     try=$(cat "$cjdns_request_tries" 2> /dev/null)
111     try=$(($try+1))
112     echo "$try" > "$cjdns_request_tries"
113
114     # try another countryserver after the 2nd try
115     if [[ "$try" -ge 2 ]]; then
116         e "switching to an alternative server"
117         curl http://127.0.0.1:8000/api/v1/set_next_country &> /dev/null
118         /usr/sbin/cfengine-apply
119     fi
120
121     # request cjdns internet via script after the 3rd try
122     if [[ "$try" -ge 3 ]]; then
123         e "request cjdns internet"
124         /usr/sbin/request-internet
125     fi
126 }
127
128 start_cjdns() {
129     if [[ "$(/etc/init.d/cjdns status)" != "running" ]]; then
130         e "starting cjdns"
131         /etc/init.d/cjdns start
132     fi
133 }
134
135 restart_cjdns() {
136     e "restarting cjdns"
137     /etc/init.d/cjdns restart
138 }
139
140 get_vpn_gateway() {
141     ifconfig tun0 2> /dev/null | grep "inet addr" | cut -d: -f2 | awk '{ print $1 }'
142 }
143
144 get_original_gateway() {
145     if [[ -f "$orggatewayfile" ]]; then
146         org_gw=$(cat "$orggatewayfile")
147     else
148         org_gw=$(route -n | grep '^0.0.0.0' | awk '{ print $2 }')
149         echo "$org_gw" > "$orggatewayfile"
150     fi
151     echo "$org_gw"
152 }
153
154 gateway_is_up() {
155     vpn_gateway=$(get_vpn_gateway)
156     if [[ "$vpn_gateway" != "" ]]; then
157         echo true
158     fi
159 }
160
161 interface_dhcp_success() {
162     if [[ "$(ifconfig "$clearnet_interface" | grep 'inet addr' | wc -l)" -gt 0 ]]; then
163         echo true
164     fi
165 }
166
167 mtu() {
168     if [[ "$(ifconfig tun0 2> /dev/null | grep -i mtu | awk '{ print $6 }' | cut -d: -f 2)" -ne 1300 ]]; then
169         e "setting mtu"
170         ifconfig tun0 mtu 1300
171     fi
172 }
173
174 original_gateway() {
175     original_gateway=$(get_original_gateway)
176     for remoteaddress in $remoteaddresses; do
177         if [[ "$(route -n | egrep "$remoteaddress.*?$original_gateway" | wc -l)" -eq 0 ]]; then
178             e "setting route $remoteaddress via $original_gateway dev $clearnet_interface"
179             route add "$remoteaddress" gw "$original_gateway" "$clearnet_interface"
180         fi
181     done
182 }
183
184 defaultroute() {
185     original_gateway=$(get_original_gateway)
186     vpn_gateway=$(get_vpn_gateway)
187     if [[ "$(route -n | egrep "0.0.0.0.*?$vpn_gateway" | wc -l)" -eq 0 ]]; then
188         e "setting defaultroute"
189         route del default
190         route add default gw "$vpn_gateway" tun0
191     fi
192 }
193
194 set_network_parameters() {
195     mtu
196     original_gateway
197     defaultroute
198 }
199
200 check_for_internet() {
201     # check for internet. if only one server with a direct route is pingable,
202     # we have an internet connection
203     for remoteaddress in $remoteaddresses; do
204         if [[ "$($ping "$remoteaddress" | grep 'bytes from')" ]]; then
205             echo true
206             break
207         fi
208     done
209 }
210
211 set_status() {
212     key=$1
213     val=$2
214     echo "$val" > "$netstat_file-$key"
215 }
216
217
218
219 # params
220 [[ "$1" == "startwifi" ]] && startwifi "$2"
221
222
223
224 # logic
225
226 # ensure dhcpd is running
227 if [[ $( pidof dhcpd | wc -l ) -eq 0 ]]; then
228     /etc/init.d/dhcpd restart
229 fi
230
231 # ensure radvd is running
232 if [[ "$(pidof radvd | wc -l)" -eq 0 ]]; then
233     /etc/init.d/radvd restart
234 fi
235
236 # setup wifi if available
237 if [[ -e "/sys/class/net/wlan0" ]]; then
238     e "wifi detected"
239
240     if [[ "$opmode" = "mesh" ]]; then
241         e "opmode: mesh"
242
243         # check if wlan0 has already started
244         if [[ "$(iwconfig wlan0 | grep 'ESSID' | grep 'cjdns' | wc -l)" -eq 0 \
245             || "$(iwconfig wlan0 | grep 'Mode:' | grep 'Ad-Hoc' | wc -l)" -eq 0 ]]; then
246             e "starting ad-hoc mesh"
247             ifconfig wlan0 down
248             iwconfig wlan0 mode ad-hoc
249             iwconfig wlan0 essid cjdns
250             ifconfig wlan0 up
251             restart_cjdns
252         else
253             e "ad-hoc mesh is running fine"
254         fi
255     fi
256
257     if [[ "$opmode" = "client" ]]; then
258         e "opmode: client"
259
260         clearnet_interface=wlan0
261
262         # check if wlan0 has already started
263         if [[ "$(ifconfig wlan0 | grep 'inet addr' | wc -l)" -eq 0 \
264             || "$(iwconfig wlan0 | grep 'Access Point: Not-Associated' | wc -l)" -gt 0 ]]; then
265             if [[ "$security" = "WPA" ]]; then
266                 start_wpa
267             else
268                 start_wep
269             fi
270         else
271             e "wlan client is running fine"
272         fi
273         #TODO: connect to unencrypted wifi
274     fi
275 fi
276
277 if [[ "$(gateway_is_up)" == "true" ]]; then
278     set_network_parameters
279     e "checking internet connectivity over cjdns"
280     if [[ "$($ping 8.8.8.8 | grep 'bytes from')" ]]; then
281         echo "We have internet. Good."
282         set_status "dhcp" 1
283         set_status "internet" 1
284         set_status "cjdns" 1
285         set_status "cjdns_internet" 1
286         rm "$cjdns_request_tries" 2> /dev/null
287         exit
288     fi
289 fi
290
291 echo "No internet via cjdns. Checking for regular internet connection..."
292 set_status "dhcp" 0
293 set_status "internet" 0
294 set_status "cjdns" 0
295 set_status "cjdns_internet" 0
296
297 # request dhcp
298 dhcp
299
300 if [[ "$(interface_dhcp_success)" == "true" ]]; then
301     set_status "dhcp" 1
302 fi
303
304 wehaveinternet="no"
305 if [[ "$(check_for_internet)" == "true" ]]; then
306     set_status "internet" 1
307     wehaveinternet="yes"
308 fi
309
310 if [[ "$wehaveinternet" == "yes" && "$request_internet" == "yes" ]]; then
311     request_cjdns_internet
312     restart_cjdns
313     set_status "cjdns" 1
314     for i in $(seq 60 -1 1); do
315         echo "waiting $i seconds for gateway to come up..."
316         if [[ "$(gateway_is_up)" == "true" ]]; then
317             e "gateway is up."
318             set_network_parameters
319             e "checking internet connectivity over cjdns"
320             if [[ "$($ping 8.8.8.8 | grep 'bytes from')" ]]; then
321                 echo "We have internet. Good."
322                 set_status "dhcp" 1
323                 set_status "internet" 1
324                 set_status "cjdns" 1
325                 set_status "cjdns_internet" 1
326                 rm "$cjdns_request_tries" 2> /dev/null
327                 exit
328             else
329                 echo "Gateway is up, but no internet. Requesting..."
330                 /usr/sbin/request-internet
331                 exit
332             fi
333         fi
334         sleep 1
335     done
336 else
337     e "no internet via cjdns."
338     # just ensure that cjdns is running, but DO NOT restart it!
339     # since local phone calls may be active.
340     start_cjdns
341     set_status "cjdns" 1
342 fi
343