firmware/src/packages/fff/fff-hoods/files/usr/sbin/configurehood
Adrian Schmutzler 6ad42be496 fff-network/fff-hoods: Only use MAC address in network lib
Previously, IPv6 addresses were constructed by reading from
the device config file in the function. To have more options,
it is better to use the address itself as parameter.

By this way we can decide what we use for getting the MAC when
calling.

Signed-off-by: Adrian Schmutzler <freifunk@adrianschmutzler.de>
Reviewed-by: Tim Niemeyer <tim@tn-x.org>
2018-01-20 14:47:58 +01:00

324 lines
11 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
resetnetworkfile=/tmp/resetnetwork
hoodlocal=/etc/hoodfile
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)
# reenable network interfaces in case we disabled them earlier
if [ -f "$resetnetworkfile" ]; then
/etc/init.d/network restart
rm "$resetnetworkfile"
fi
if [ -s "$hoodlocal" ]; then
hoodfile="$hoodlocal"
echo "Use local hood file"
else
# 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"
sleep 30 # Wait for the config AP, which may be created at the same time as this script has started
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"
# check eth first
oldhood=""
ethfile="${hoodfile}eth"
for eth in $(batctl if | grep "eth" | sed -nE 's/.*(eth[^:]+):.*/\1/p'); do
for mac in $(batctl n | grep "$eth" | sed -nE 's/.*eth[0-9.]+\s+([^\s]+)\s.*/\1/p'); do
EUI="$(echo "$mac" | awk -F: '{ printf("%02x%s:%sff:fe%s:%s%s\n", xor(("0x"$1),2), $2, $3, $4, $5, $6) }')"
wget -T2 -t3 "http://[fe80::${EUI}%${eth}]:2342/keyxchangev2data" -O "$ethfile"
if [ -s "$ethfile" ]; then
json_load "$(cat "$ethfile")"
json_select hood
json_get_var newhood name
if [ -n "$oldhood" ] && [ -n "$newhood" ] && ( ! [ "$newhood" = "$oldhood" ] ) ; then
# 2nd hood found, kill interface and go on (next try in 5 min.)
echo "Two hoods detected. Remove cables to stay in just one."
ifconfig "$eth" down
touch "$resetnetworkfile"
continue 2 # go to the next interface
fi
mv "$ethfile" "$hoodfile" # Only use hoodfile if sane
[ -n "$oldhood" ] || oldhood="$newhood" # only set oldhood once
fi
done
done
if [ ! -s "$hoodfile" ]; then
# Only load hoodfile from gateway if not already present from local network
# - This gives local network a precedence (take the hood from local network)
# - This prevents file insertion from a third person, as I will only connect via LAN to who I trust
wget -T15 -t5 "http://[fe80::1%br-mesh]:2342/keyxchangev2data" -O "$hoodfile"
fi
#UPLINK: Do nothing
fi
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,\\,,')"
mac="$(cat "/sys/class/net/br-mesh/address")"
addr="$(ipMacAssemble "$prefix" "$mac")"
addr="$(ipTidyColon "$addr")"
addr_eui="$(ipEUIAssemble "$prefix" "$mac")"
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