forked from freifunk-franken/firmware
280 lines
8.9 KiB
Bash
Executable File
280 lines
8.9 KiB
Bash
Executable File
#!/bin/sh
|
|
|
|
. /usr/share/libubox/jshn.sh
|
|
. /lib/functions/fff/keyxchange
|
|
. /lib/functions/fff/network
|
|
. /lib/functions/fff/wireless
|
|
. /lib/functions/fff/timeserver
|
|
|
|
sectorlocal=/etc/sectorfile
|
|
sectortmp=/tmp/sectorfile
|
|
sectorcopy=/www/hood/sectorfile
|
|
hiddenapfile=/tmp/hiddenapflag
|
|
|
|
rm -f "$hoodfile"
|
|
|
|
# Gatewaycheck function
|
|
isGatewayAvailable() {
|
|
if [ "$(batctl gwl | wc -l)" -gt 2 ]; then
|
|
return 0
|
|
else
|
|
return 1
|
|
fi
|
|
}
|
|
|
|
# Ping test
|
|
hasInternet() {
|
|
test_ipv4_host1="keyserver.freifunk-franken.de" # Freifunk-Franken keyserver
|
|
test_ipv4_host2="8.8.8.8" # Google DNS
|
|
test_ipv6_host1="heise.de" # heise Zeitschriftenverlag
|
|
if ping -w5 -c3 "$test_ipv4_host1" &>/dev/null ||
|
|
ping -w5 -c3 "$test_ipv4_host2" &>/dev/null ||
|
|
ping6 -w5 -c3 "$test_ipv6_host1" &>/dev/null ; then
|
|
return 0
|
|
fi
|
|
return 1
|
|
}
|
|
|
|
# Hidden AP check
|
|
|
|
if [ -f "$hiddenapfile" ]; then
|
|
if isGatewayAvailable ; then
|
|
|
|
for radio in $(uci show wireless | sed -n 's,.*\.\([a-z0-9]*\)=wifi-device,\1,p'); do
|
|
channel=$(uci get "wireless.${radio}.channel")
|
|
iface="configap2"
|
|
if [ "$channel" -gt "14" ]; then
|
|
iface="configap5"
|
|
fi
|
|
uci set network.${iface}=interface
|
|
uci set network.${iface}.proto='static'
|
|
uci set network.${iface}.ip6addr='fe80::1/64'
|
|
if ! wifiAddAP "$radio" "config.franken.freifunk.net" "$iface" "configap" "1"; then
|
|
echo "Can't add Config interface on $radio."
|
|
exit 1
|
|
fi
|
|
done
|
|
uci commit network
|
|
|
|
wifi
|
|
|
|
rm "$hiddenapfile"
|
|
fi
|
|
fi
|
|
|
|
lat=$(uci -q get fff.system.latitude)
|
|
long=$(uci -q get fff.system.longitude)
|
|
|
|
# if we have Internet, we download the Hoodfile from the keyxchangev2
|
|
if hasInternet ; then
|
|
wget -T15 -t5 "http://keyserver.freifunk-franken.de/v2/?lat=$lat&long=$long" -O "$hoodfile"
|
|
rm -f "$sectortmp"
|
|
[ -s "$sectorlocal" ] || rm -f "$sectorcopy" # If internet present, no custom config should be distributed, except when local file is present
|
|
#UPLINK: No uplink download if internet present
|
|
#if no Internet, we connect to the hidden AP and download the file from another Node in range
|
|
else
|
|
# connect to wireless hidden ap here and download the json File from the nearest router
|
|
# Only do that, when we have no gateway in range. If the Uplinkrouter changed the hood, we lost the GW and do this automatically again, I think! Nice idea?
|
|
if ! isGatewayAvailable ; then
|
|
#now we haven't a gateway in Range, we search for a hidden AP to get a keyxchangev2data file!
|
|
#first we delete all wifi settings
|
|
rm -f "$hoodfilecopy" # delete this, so interfaces are recreated if reconnect with unchanged hood file takes place
|
|
rm -f "$sectorcopy" # always delete: no broadcast for isolated device
|
|
rm -f "$sectortmp"
|
|
|
|
if ! wifiDelIface; then
|
|
echo "Can't delete current wifi setup"
|
|
exit 1
|
|
fi
|
|
#now we look for phy and add this
|
|
for phy in $(iw phy | awk '/^Wiphy/{ print $2 }'); do
|
|
radio="$(wifiAddPhyCond "$phy" "2" "auto")"
|
|
radio5="$(wifiAddPhyCond "$phy" "5" "auto5")"
|
|
if [ -n "$radio5" ] ; then
|
|
radio="$radio5"
|
|
staiface="w5sta"
|
|
else
|
|
staiface="w2sta"
|
|
fi
|
|
|
|
#and here we add the station
|
|
if ! wifiAddSta "$radio" "config.franken.freifunk.net" "configSta" "$staiface" ; then
|
|
echo "Can't add Sta interface on $radio."
|
|
exit 1
|
|
else
|
|
uci -q set network.configSta=interface
|
|
uci -q set network.configSta.proto='static'
|
|
uci -q commit network
|
|
fi
|
|
done
|
|
|
|
wifi
|
|
# wait a moment to start the interface
|
|
sleep 10;
|
|
# and here we can download the Hoodfile from the other node
|
|
wget -T15 -t5 "http://[fe80::1%w2sta]:2342/keyxchangev2data" -O "$hoodfile" || wget -T15 -t5 "http://[fe80::1%w5sta]:2342/keyxchangev2data" -O "$hoodfile"
|
|
#UPLINK: Set up uplink data on first contact:
|
|
if [ -s /tmp/keyxchangev2data ]; then
|
|
wget -T15 -t5 "http://[fe80::1%w2sta]:2342/sectorfile" -O "$sectortmp" || wget -T15 -t5 "http://[fe80::1%w5sta]:2342/sectorfile" -O "$sectortmp"
|
|
fi
|
|
else
|
|
echo "We have a Gateway in Range, we load the keyxchangev2data from fe80::1"
|
|
wget -T15 -t5 "http://[fe80::1%br-mesh]:2342/keyxchangev2data" -O "$hoodfile"
|
|
#UPLINK: Do nothing
|
|
fi
|
|
fi
|
|
|
|
if [ -s "$hoodfile" ]; then
|
|
|
|
# we get a json file in this format:
|
|
# https://pw.freifunk-franken.de/patch/205/
|
|
# but without signature, every hood file we get is valid!
|
|
|
|
[ -s "$sectorlocal" ] && sectortmp="$sectorlocal" # Use local file if present (configuration set by user)
|
|
if [ -s "$sectortmp" ] ; then
|
|
json_load "$(cat "$sectortmp")"
|
|
json_select hood
|
|
json_get_var mesh_id mesh_id
|
|
json_get_var mesh_bssid mesh_bssid
|
|
json_get_var mesh_essid mesh_essid
|
|
json_get_var essid essid
|
|
json_get_var chan2ghz channel2
|
|
json_get_var mesh_type2 mesh_type2
|
|
json_get_var chan5ghz channel5
|
|
json_get_var mesh_type5 mesh_type5
|
|
fi
|
|
|
|
catnew="$(cat "$hoodfile" | sed 's/"timestamp”: *"[0-9]*"/"timestamp":0/')"
|
|
catold="$(cat "$hoodfilecopy" 2>/dev/null | sed 's/"timestamp”: *"[0-9]*"/"timestamp":0/')"
|
|
sumnew=$(echo "$catnew" | sha256sum | cut -f1 -d " ")
|
|
sumold=$(echo "$catold" | sha256sum | cut -f1 -d " ")
|
|
|
|
json_load "$(cat "$hoodfile")"
|
|
|
|
if [ "$sumnew" != "$sumold" ] ; then
|
|
echo "New file detected, we reconfigure the Node";
|
|
|
|
json_select hood
|
|
|
|
json_get_var hood name
|
|
[ -n "$mesh_id" ] || json_get_var mesh_id mesh_id
|
|
[ -n "$mesh_bssid" ] || json_get_var mesh_bssid mesh_bssid
|
|
[ -n "$mesh_essid" ] || json_get_var mesh_essid mesh_essid
|
|
[ -n "$essid" ] || json_get_var essid essid
|
|
json_get_var ntpip ntp_ip
|
|
[ -n "$chan2ghz" ] || json_get_var chan2ghz channel2
|
|
[ -n "$mesh_type2" ] || json_get_var mesh_type2 mesh_type2
|
|
[ -n "$chan5ghz" ] || json_get_var chan5ghz channel5
|
|
[ -n "$mesh_type5" ] || json_get_var mesh_type5 mesh_type5
|
|
# Additional parameters may be activated in future versions
|
|
#json_get_var mode2 mode2
|
|
#json_get_var mode5 mode5
|
|
#json_get_var protocol protocol
|
|
|
|
json_select ".." # back to root
|
|
|
|
if ! ([ -n "$chan2ghz" ] && [ -n "$chan5ghz" ]) ; then
|
|
# If channel is missing, do nothing
|
|
exit 0
|
|
fi
|
|
|
|
echo "Setting hood name: $hood"
|
|
uci -q set "system.@system[0].hood=$hood"
|
|
uci -q commit system
|
|
|
|
if ! wifiDelIface; then
|
|
echo "Can't delete current wifi setup"
|
|
exit 1
|
|
fi
|
|
|
|
for phy in $(iw phy | awk '/^Wiphy/{ print $2 }'); do
|
|
radio="$(wifiAddPhyCond "$phy" "2" "$chan2ghz")"
|
|
radio5="$(wifiAddPhyCond "$phy" "5" "$chan5ghz")"
|
|
[ -n "$radio5" ] && radio="$radio5"
|
|
|
|
if ! wifiAddAP "$radio" "$essid" "mesh" "ap" "0"; then
|
|
echo "Can't add AP interface on $radio."
|
|
exit 1
|
|
fi
|
|
|
|
# here we set a bit for add hidden AP
|
|
touch "$hiddenapfile"
|
|
|
|
# add 802.11s mesh if type == "802.11s"
|
|
if ( [ -n "$radio5" ] && [ "$mesh_type5" == "802.11s" ] ) || [ "$mesh_type2" == "802.11s" ]; then
|
|
if ! wifiAddMesh "$radio" "$mesh_id"; then
|
|
echo "Can't add Mesh interface on $radio."
|
|
exit 1
|
|
fi
|
|
fi
|
|
|
|
# add IBSS mesh if type == "ibss"
|
|
if ( [ -n "$radio5" ] && [ "$mesh_type5" == "ibss" ] ) || [ "$mesh_type2" == "ibss" ]; then
|
|
if ! wifiAddAdHocMesh "$radio" "$mesh_essid" "$mesh_bssid"; then
|
|
echo "Can't add AdHocMesh interface on $radio."
|
|
exit 1
|
|
fi
|
|
fi
|
|
done
|
|
|
|
echo "Loading wifi"
|
|
wifi
|
|
|
|
oldntp="$(uci -q get system.ntp.server)"
|
|
newntp="${ntpip}" # requires routable address, no link-local
|
|
[ "$newntp" = "$oldntp" ] || setTimeserver "${newntp}" # only rewrite if changed
|
|
|
|
# copy the file to webroot so that other mesh routers can download it;
|
|
# copy only after all other steps so IF can be reentered if something goes wrong
|
|
cp "$hoodfile" "$hoodfilecopy"
|
|
[ -s "$sectortmp" ] && cp "$sectortmp" "$sectorcopy"
|
|
|
|
else
|
|
echo "We have no new file. We do nothing. We try it again in 5 minutes...";
|
|
fi
|
|
|
|
# and now we get to vpn-select script and load VPNs directly from /tmp/keyxchangev2data
|
|
|
|
if hasInternet ; then
|
|
sh /usr/sbin/vpn-select
|
|
fi
|
|
|
|
# now we load the prefix from the hoodfile and set this to br-mesh
|
|
json_select network
|
|
json_get_var prefix ula_prefix
|
|
# Set $prefix::MAC as IP
|
|
if [ -n "$prefix" ] ; then
|
|
prefix="$(echo "$prefix" | sed -e 's,\\,,')"
|
|
addr="$(ipMacAssemble "$prefix" "br-mesh")"
|
|
addr="$(ipTidyColon "$addr")"
|
|
addr_eui="$(ipEUIAssemble "$prefix" "br-mesh")"
|
|
addr_eui="$(ipTidyColon "$addr_eui")"
|
|
for ip in $(ip -6 addr show dev br-mesh | grep inet6 | grep -v -e " $addr" -e " $addr_eui" -e " fe80::" -e " fdff::" | cut -f6 -d " "); do
|
|
ip -6 addr del "$ip" dev br-mesh
|
|
done
|
|
if ! ( ip -6 addr show dev br-mesh | grep -q "$addr" ) ; then
|
|
ip -6 addr add "$addr" dev br-mesh
|
|
echo "Set ULA address to br-mesh: $addr"
|
|
else
|
|
echo "Address already set."
|
|
fi
|
|
# Set $prefix::link-local as IP
|
|
if ! ( ip -6 addr show dev br-mesh | grep -q "$addr_eui" ) ; then
|
|
ip -6 addr add "$addr_eui" dev br-mesh
|
|
echo "Set ULA EUI-64 address to br-mesh: $addr_eui"
|
|
else
|
|
echo "Address already set."
|
|
fi
|
|
if ! ( ip -6 route show dev br-mesh | grep -q "fc00::" ) ; then
|
|
ip -6 route add fc00::/7 via fe80::1 dev br-mesh
|
|
echo "Set ULA route to br-mesh."
|
|
else
|
|
echo "Route already set."
|
|
fi
|
|
fi
|
|
json_select ".." # back to root
|
|
else
|
|
echo "We haven't got a file. We do nothing. We try it again in 5 minutes...";
|
|
exit 0
|
|
fi
|