Permalink
Switch branches/tags
Nothing to show
Find file Copy path
Fetching contributors…
Cannot retrieve contributors at this time
457 lines (377 sloc) 11.7 KB
#!/bin/ash
export LC_ALL=en_US.UTF-8
# TODO
# * dns und gateway vom dhcp-server übernehmen, erst setzen, wenn ip erhalten
# vars
remoteaddresses="{{#peerings}}{{ip}} {{/peerings}}{{#missioncontrol}}{{ip}} {{/missioncontrol}}"
internethosts="91.219.237.212 8.8.8.8"
orggatewayfile="/tmp/cjdns_org_gw"
network_profile="$(cat /etc/enigmabox/network-profile)"
if [[ "$network_profile" = "alix" ]]; then
clearnet_interface="eth0"
internal_interfaces="eth1 eth2"
fi
if [[ "$network_profile" = "apu" ]]; then
clearnet_interface="eth2"
internal_interfaces="eth1 eth0"
fi
if [[ "$network_profile" = "raspi" ]]; then
clearnet_interface="eth1"
internal_interfaces="eth0"
fi
ping="ping -c 5 -W 5"
cjdns_request_tries="/tmp/cjdns_request_tries"
netstat_file="/tmp/netstat"
pidfile="/tmp/setup-cjdns-networking.pid"
opmode="{{wlan_opmode}}"
ssid="{{wlan_ssid}}"
wep_pass="{{wlan_pass}}"
security="{{wlan_security}}"
dynamic_output="/tmp/dynamic_output"
{{#if_internet_gateway}}
request_internet="yes"
{{/if_internet_gateway}}
{{^if_internet_gateway}}
request_internet="no"
{{/if_internet_gateway}}
# check if its already running
if [[ "$1" != "startwifi" ]]; then
kill -0 $(cat "$pidfile" 2> /dev/null) 2> /dev/null
if [[ "$?" == "0" ]]; then
echo "script is already running"
exit 0
fi
echo $$ > "$pidfile"
fi
# functions
e() {
echo 1>&2
echo 1>&2
echo "$1" 1>&2
}
startwifi() {
echo "please wait, configuring system..." > "$dynamic_output"
/usr/sbin/cfengine-apply &> /dev/null
echo "done" > "$dynamic_output"
/usr/sbin/setup-cjdns-networking &> "$dynamic_output"
exit 0 #the script should end here
}
dhcp() {
ifconfig "$clearnet_interface" up
if [[ $(ifconfig "$clearnet_interface" | grep 'inet addr' | wc -l) -eq 0 ]]; then
e "dhcp request $clearnet_interface"
udhcpc -i "$clearnet_interface" --now
fi
if [[ $(route -n | grep ^0.0.0.0 | wc -l) -eq 0 ]]; then
e "dhcp request $clearnet_interface"
udhcpc -i "$clearnet_interface" --now
fi
}
start_wpa() {
e "start WPA session"
ifconfig wlan0 down
killall wpa_supplicant
# make sure wpa_supplicant is absent
rm "/var/run/wpa_supplicant/wlan0" 2> /dev/null
sleep 2
ifconfig wlan0 up
wpa_supplicant -i wlan0 -D wext -c /etc/wpa_supplicant/wpa_supplicant.conf -B
sleep 2
}
start_wep() {
{{#if_wlan_pass}}
e "start WEP session"
ifconfig wlan0 up
iwconfig wlan0 essid "$ssid"
iwconfig wlan0 key "d:0:$wep_pass"
{{/if_wlan_pass}}
{{^if_wlan_pass}}
e "connecting to AP"
ifconfig wlan0 up
iwconfig wlan0 essid "$ssid"
{{/if_wlan_pass}}
}
request_cjdns_internet() {
try=$(cat "$cjdns_request_tries" 2> /dev/null)
try=$(($try+1))
echo "$try" > "$cjdns_request_tries"
# try another countryserver on the 2nd try
if [[ "$try" -eq 2 ]]; then
e "switching to an alternative server"
curl http://127.0.0.1:8000/api/v1/set_next_country &> /dev/null
/usr/sbin/cfengine-apply
fi
# request server.json on the 3rd try
if [[ "$try" -eq 3 ]]; then
e "request server.json"
/usr/sbin/request-serverjson
/usr/sbin/cfengine-apply
fi
# request cjdns internet via script on the 4th try
if [[ "$try" -eq 4 ]]; then
e "request cjdns internet"
/usr/sbin/request-internet
fi
# reset counter after 5th try, start from the beginning
if [[ "$try" -ge 5 ]]; then
echo 1 > "$cjdns_request_tries"
fi
}
start_cjdns() {
if [[ "$(/etc/init.d/cjdns status)" != "running" ]]; then
e "starting cjdns"
/etc/init.d/cjdns start
fi
}
restart_cjdns() {
e "restarting cjdns"
/etc/init.d/cjdns restart
}
portforwardings() {
{{#portforwardings}}
start_portforwarding "{{port}}" "{{mac}}" "{{dstport}}"
{{/portforwardings}}
sleep 1
# kill disabled tunnels
for af in $(netstat -tulpen | grep socat | awk '{ print $4 }' | cut -d: -f4 | sort | uniq); do
if [[ $(echo "{{#portforwardings}}{{port}} {{/portforwardings}}" | grep "$af " | wc -l) -eq 0 ]]; then
echo "stopping port forwarding $af"
kill $(netstat -tulpen | grep ":::$af " | awk '{ print $7 }' | cut -d/ -f1) &> /dev/null
kill $(netstat -tulpen | grep ":::$af " | awk '{ print $6 }' | cut -d/ -f1) &> /dev/null
fi
done
}
start_portforwarding() {
port=$1
mac=$2
dstport=$3
# don't start forwarding if ip is not up
[[ $(mactoip "$mac") == "" ]] && return
if [[ "$(netstat -tulpen | grep socat | grep tcp | grep :::$port | wc -l)" -eq 0 ]]; then
echo "starting port forwarding $port TCP"
/usr/bin/socat TCP6-LISTEN:$port,reuseaddr,fork TCP:$(mactoip "$mac"):$dstport &
fi
if [[ "$(netstat -tulpen | grep socat | grep udp | grep :::$port | wc -l)" -eq 0 ]]; then
echo "starting port forwarding $port UDP"
/usr/bin/socat UDP6-LISTEN:$port,reuseaddr,fork UDP:$(mactoip "$mac"):$dstport &
fi
}
mactoip() {
cat /proc/net/arp | grep "$1" | cut -d' ' -f1
}
get_vpn_gateway() {
ifconfig tun0 2> /dev/null | grep "inet addr" | cut -d: -f2 | awk '{ print $1 }'
}
get_original_gateway() {
if [[ -f "$orggatewayfile" ]]; then
org_gw=$(cat "$orggatewayfile")
else
org_gw=$(route -n | grep '^0.0.0.0' | awk '{ print $2 }')
echo "$org_gw" > "$orggatewayfile"
fi
echo "$org_gw"
}
gateway_is_up() {
vpn_gateway=$(get_vpn_gateway)
if [[ "$vpn_gateway" != "" ]]; then
echo true
fi
}
we_have_internet() {
for internethost in $internethosts; do
if [[ "$($ping "$internethost" | grep 'bytes from')" ]]; then
echo true
break
fi
done
}
interface_dhcp_success() {
if [[ "$(ifconfig "$clearnet_interface" | grep 'inet addr' | wc -l)" -gt 0 ]]; then
echo true
fi
}
interface_dhcp_conflict() {
clearnet_range=$(ifconfig "$clearnet_interface" | grep 'inet addr' | cut -d. -f3)
for interface in $internal_interfaces; do
if [[ "$(ifconfig "$interface" | grep 'inet addr' | cut -d. -f3)" == "$clearnet_range" ]]; then
echo true
break
fi
done
}
mtu() {
if [[ "$(ifconfig tun0 2> /dev/null | grep -i mtu | awk '{ print $6 }' | cut -d: -f 2)" -ne 1300 ]]; then
e "setting mtu"
ifconfig tun0 mtu 1300
fi
}
original_gateway() {
original_gateway=$(get_original_gateway)
for remoteaddress in $remoteaddresses; do
if [[ "$(route -n | egrep "$remoteaddress.*?$original_gateway" | wc -l)" -eq 0 ]]; then
e "setting route $remoteaddress via $original_gateway dev $clearnet_interface"
route add "$remoteaddress" gw "$original_gateway" "$clearnet_interface"
fi
done
}
defaultroute() {
vpn_gateway=$(get_vpn_gateway)
if [[ "$(route -n | egrep "0.0.0.0.*?$vpn_gateway" | wc -l)" -eq 0 ]]; then
e "setting defaultroute"
route del default
route add default gw "$vpn_gateway" tun0
fi
if [[ "$(route -A inet6 | egrep '::/0' | wc -l)" -eq 0 ]]; then
e "setting defaultroute ipv6"
route -A inet6 del default
route -A inet6 add default tun0
fi
}
set_network_parameters() {
mtu
portforwardings
original_gateway
defaultroute
(
for i in $(seq 1 60); do
sleep 1
defaultroute
done
) &
}
check_for_internet() {
# check for internet. if only one server with a direct route is pingable,
# we have an internet connection
for remoteaddress in $remoteaddresses; do
if [[ "$($ping "$remoteaddress" | grep 'bytes from')" ]]; then
echo true
break
fi
done
}
set_status() {
key=$1
val=$2
echo "$val" > "$netstat_file-$key"
}
# params
[[ "$1" == "startwifi" ]] && startwifi "$2"
# logic
# ensure dhcpd is running
if [[ $( pidof dhcpd | wc -l ) -eq 0 ]]; then
/etc/init.d/dhcpd restart
fi
# ensure radvd is running
if [[ "$(pidof radvd | wc -l)" -eq 0 ]]; then
/etc/init.d/radvd restart
fi
# setup wifi if available
if [[ -e "/sys/class/net/wlan0" ]]; then
e "wifi detected"
if [[ "$opmode" = "mesh" ]]; then
e "opmode: mesh"
# check if wlan0 has already started
if [[ "$(iwconfig wlan0 | grep 'ESSID' | grep 'cjdns' | wc -l)" -eq 0 \
|| "$(iwconfig wlan0 | grep 'Mode:' | grep 'Ad-Hoc' | wc -l)" -eq 0 ]]; then
e "starting ad-hoc mesh"
ifconfig wlan0 down
iwconfig wlan0 mode ad-hoc
iwconfig wlan0 essid cjdns
ifconfig wlan0 up
restart_cjdns
else
e "ad-hoc mesh is running fine"
fi
fi
if [[ "$opmode" = "client" ]]; then
e "opmode: client"
clearnet_interface=wlan0
# check if wlan0 has already started
if [[ "$(ifconfig wlan0 | grep 'inet addr' | wc -l)" -eq 0 \
|| "$(iwconfig wlan0 | grep 'Access Point: Not-Associated' | wc -l)" -gt 0 ]]; then
if [[ "$security" = "WPA" ]]; then
start_wpa
else
start_wep
fi
else
e "wlan client is running fine"
fi
#TODO: connect to unencrypted wifi
fi
fi
# set MWI status for the phone
if [[ $(/usr/bin/find /box/vmail/mail/Maildir/new/ -type f 2> /dev/null | wc -l) -gt 0 ]]; then
/usr/sbin/asterisk -rx 'sip notify set-mwi 100' &> /dev/null
else
/usr/sbin/asterisk -rx 'sip notify clear-mwi 100' &> /dev/null
fi
if [[ "$(gateway_is_up)" == "true" ]]; then
set_network_parameters
e "checking internet connectivity over cjdns"
if [[ "$(we_have_internet)" == "true" ]]; then
echo "We have internet. Good."
set_status "dhcp" 1
set_status "internet" 1
set_status "cjdns" 1
set_status "cjdns_internet" 1
rm "$cjdns_request_tries" 2> /dev/null
exit
fi
fi
echo "No internet via cjdns. Checking for regular internet connection..."
set_status "dhcp" 0
rm "$netstat_file-dhcp_conflict" 2> /dev/null
set_status "internet" 0
set_status "cjdns" 0
set_status "cjdns_internet" 0
# request dhcp
dhcp
if [[ "$(interface_dhcp_success)" == "true" ]]; then
set_status "dhcp" 1
fi
if [[ "$(interface_dhcp_conflict)" == "true" ]]; then
ifconfig "$clearnet_interface" | grep 'inet addr' | cut -d: -f2 | cut -d' ' -f1 > "$netstat_file-dhcp_conflict"
exit
fi
wehaveinternet="no"
if [[ "$(check_for_internet)" == "true" ]]; then
set_status "internet" 1
wehaveinternet="yes"
fi
if [[ "$wehaveinternet" == "yes" && "$request_internet" == "yes" ]]; then
request_cjdns_internet
restart_cjdns
set_status "cjdns" 1
for i in $(seq 60 -1 1); do
echo "waiting $i seconds for gateway to come up..."
if [[ "$(gateway_is_up)" == "true" ]]; then
e "gateway is up."
set_network_parameters
e "checking internet connectivity over cjdns"
if [[ "$(we_have_internet)" == "true" ]]; then
echo "We have internet. Good."
set_status "dhcp" 1
set_status "internet" 1
set_status "cjdns" 1
set_status "cjdns_internet" 1
rm "$cjdns_request_tries" 2> /dev/null
exit
else
echo "Gateway is up, but no internet. Requesting..."
/usr/sbin/request-internet
exit
fi
fi
sleep 1
done
else
e "no internet via cjdns."
# just ensure that cjdns is running, but DO NOT restart it!
# since local phone calls may be active.
start_cjdns
set_status "cjdns" 1
# 6. Nov. 2018: Possible fix for boxes that won't come up
/usr/sbin/request-serverjson
/usr/sbin/cfengine-apply
fi