Skip to content
GitLab
Explore
Sign in
Register
Primary navigation
Search or go to…
Project
packages
Manage
Activity
Members
Labels
Plan
Issues
Issue boards
Milestones
External wiki
Code
Merge requests
Repository
Branches
Commits
Tags
Repository graph
Compare revisions
Deploy
Releases
Model registry
Monitor
Incidents
Service Desk
Analyze
Value stream analytics
Contributor analytics
Repository analytics
Model experiments
Help
Help
Support
GitLab documentation
Compare GitLab plans
Community forum
Contribute to GitLab
Provide feedback
Keyboard shortcuts
?
Snippets
Groups
Projects
Show more breadcrumbs
Firmware
packages
Commits
9705739b
Commit
9705739b
authored
8 years ago
by
Jan-Tarek Butt
Browse files
Options
Downloads
Patches
Plain Diff
Revert "Merge branch 'hoodselector-tarek'"
This reverts commit
a46d327c
, reversing changes made to
ea6a9eb4
.
parent
a46d327c
No related branches found
Branches containing commit
No related tags found
Tags containing commit
No related merge requests found
Changes
1
Hide whitespace changes
Inline
Side-by-side
Showing
1 changed file
hoodselector/files/usr/sbin/hoodselector
+513
-257
513 additions, 257 deletions
hoodselector/files/usr/sbin/hoodselector
with
513 additions
and
257 deletions
hoodselector/files/usr/sbin/hoodselector
+
513
−
257
View file @
9705739b
...
@@ -35,23 +35,21 @@
...
@@ -35,23 +35,21 @@
-- PID file to ensure the hoodselector isn't running parallel
-- PID file to ensure the hoodselector isn't running parallel
local
pidPath
=
"/var/run/hoodselector.pid"
local
pidPath
=
"/var/run/hoodselector.pid"
if
io.open
(
pidPath
,
'r'
)
~=
nil
then
if
io.open
(
pidPath
,
"r"
)
~=
nil
then
io.stderr
:
write
(
"The hoodselector is still running.\n"
)
io.stderr
:
write
(
"The hoodselector is still running.\n"
)
os.exit
(
1
)
os.exit
(
1
)
else
else
io.close
(
io.open
(
pidPath
,
'w'
))
io.close
(
io.open
(
pidPath
,
"w"
))
end
end
local
json
=
require
(
'
dkjson
'
)
local
json
=
require
(
"
dkjson
"
)
local
uci
=
require
(
'luci.model.uci'
).
cursor
()
local
uci
=
require
(
'luci.model.uci'
).
cursor
()
local
file
=
"
/lib/ffnw/hoods/hoods.json
"
local
file
=
'
/lib/ffnw/hoods/hoods.json
'
-- initialization done
-- initialization done
-- Read the full hoodfile. Return nil for wrong format or no such file
-- Read the full hoodfile. Return nil for wrong format or no such file
local
function
readHoodfile
(
file
)
local
function
readHoodfile
(
file
)
local
jhood
=
io.open
(
file
,
'r'
)
local
obj
,
pos
,
err
=
json
.
decode
(
io.popen
(
string.format
(
"cat %s"
,
file
),
'r'
):
read
(
'*a'
),
1
,
nil
)
if
not
jhood
then
return
nil
end
local
obj
,
pos
,
err
=
json
.
decode
(
jhood
:
read
(
'*a'
),
1
,
nil
)
if
err
then
if
err
then
return
nil
return
nil
else
else
...
@@ -61,13 +59,75 @@ end
...
@@ -61,13 +59,75 @@ end
-- Program terminating function including removing of PID file
-- Program terminating function including removing of PID file
local
function
exit
()
local
function
exit
()
if
io.open
(
pidPath
,
'r'
)
~=
nil
then
if
io.open
(
pidPath
,
"r"
)
~=
nil
then
os.remove
(
pidPath
)
os.remove
(
pidPath
)
end
end
os.exit
(
0
)
os.exit
(
0
)
end
end
-- Get a list of wifi devices return an emty table for no divices
function
trim
(
s
)
-- from PiL2 20.4
return
(
s
:
gsub
(
"^%s*
(
.-
)
%s*$"
,
"%1"
))
end
function
sleep
(
n
)
os.execute
(
"sleep "
..
tonumber
(
n
))
end
---
-- Function to retrieve console output
--
function
os
.
capture
(
cmd
,
raw
)
local
handle
=
assert
(
io.popen
(
cmd
,
'r'
))
local
output
=
assert
(
handle
:
read
(
'*a'
))
handle
:
close
()
if
raw
then
return
output
end
output
=
string.gsub
(
string.gsub
(
string.gsub
(
output
,
'^%s+'
,
''
),
'%s+$'
,
''
),
'[\n\r]+'
,
' '
)
return
output
end
local
function
vpn_stop
()
os.execute
(
'/etc/init.d/fastd stop'
)
io.stderr
:
write
(
'VPN stopped.\n'
)
end
local
function
vpn_start
()
os.execute
(
'/etc/init.d/fastd start'
)
io.stderr
:
write
(
'VPN started.\n'
)
end
local
function
vpn_disable
()
-- disable VPN if not already disabled
os.execute
(
'/etc/init.d/fastd disable'
)
io.stderr
:
write
(
'VPN disabled.\n'
)
end
local
function
vpn_enable
()
-- enable VPN if not already enabled
os.execute
(
'/etc/init.d/fastd enable'
)
end
local
function
wireless_restart
()
os.execute
(
'wifi'
)
io.stderr
:
write
(
'Wireless restarted.\n'
)
end
-- Return a wifi device list
local
function
getWifiDevices
()
local
function
getWifiDevices
()
local
radios
=
{}
local
radios
=
{}
uci
:
foreach
(
'wireless'
,
'wifi-device'
,
uci
:
foreach
(
'wireless'
,
'wifi-device'
,
...
@@ -78,16 +138,205 @@ local function getWifiDevices()
...
@@ -78,16 +138,205 @@ local function getWifiDevices()
return
radios
return
radios
end
end
-- bool if direct VPN. The detection is realaise by searching the fastd network interface inside the originator table
-- This method returns an one dimensional array containing the SSIDs for the
-- Freifunk mesh network configured in the site.conf (on dualband routers
-- one can have two mesh SSIDs. One for 2,4Ghz and one for 5Ghz).
local
function
get_mesh_ssids
()
local
site_src
=
"/lib/gluon/site.json"
local
site
,
pos
,
err
=
json
.
decode
(
io.popen
(
string.format
(
"cat %s"
,
site_src
),
'r'
):
read
(
'*a'
),
1
,
nil
)
if
err
then
io.stderr
:
write
(
"Error reading file "
..
site_src
..
"
\n
"
)
io.stderr
:
write
(
"Existing...\n"
)
exit
()
end
local
ssids
=
{}
if
(
site
.
wifi24
.
ibss
.
ssid
~=
nil
)
then
table.insert
(
ssids
,
site
.
wifi24
.
ibss
.
ssid
)
end
if
(
site
.
wifi5
.
ibss
.
ssid
~=
nil
)
then
table.insert
(
ssids
,
site
.
wifi5
.
ibss
.
ssid
)
end
return
ssids
end
-- Scans for wireless networks and returns a two dimensional array containing
-- wireless networks and their properties.
-- The array is sorted descending by signal strength (strongest signal
-- first, usually the local signal of the wireless chip of the router)
local
function
wlan_list_sorted
(
radios
)
local
networks
=
{}
for
index
,
radio
in
ipairs
(
radios
)
do
local
ifname
=
uci
:
get
(
'wireless'
,
'ibss_'
..
radio
,
'ifname'
)
if
(
ifname
~=
nil
)
then
local
wireless_scan
=
string.format
(
"iw %s scan"
,
ifname
)
local
row
=
{}
row
[
"encryption"
]
=
"open"
row
[
"radio"
]
=
radio
-- loop through each line in the output of iw
for
wifiscan
in
io.popen
(
wireless_scan
,
'r'
):
lines
()
do
-- the following line matches a new network in the output of iw
if
wifiscan
:
match
(
"BSS (%w+:%w+:%w+:%w+:%w+:%w+)"
)
then
if
(
row
[
"bssid"
]
~=
nil
and
row
[
"quality"
]
~=
nil
and
row
[
"ssid"
]
~=
nil
and
row
[
"capability"
]
~=
nil
)
then
table.insert
(
networks
,
row
)
row
=
{}
row
[
"encryption"
]
=
"open"
row
[
"radio"
]
=
radio
end
end
-- get encryption
if
wifiscan
:
match
(
"WPA:"
)
then
row
[
"encryption"
]
=
"WPA"
end
if
wifiscan
:
match
(
"WEP:"
)
then
row
[
"encryption"
]
=
"WEP"
end
if
wifiscan
:
match
(
"RSN:"
)
then
row
[
"encryption"
]
=
"RSN"
end
-- get ssid
if
wifiscan
:
match
(
"SSID:"
)
then
row
[
"ssid"
]
=
wifiscan
:
split
(
":"
)
row
[
"ssid"
]
=
row
[
"ssid"
][
2
]
if
(
row
[
"ssid"
]
~=
nil
)
then
row
[
"ssid"
]
=
trim
(
row
[
"ssid"
])
end
end
-- get frequency
if
wifiscan
:
match
(
"freq:"
)
then
row
[
"frequency"
]
=
wifiscan
:
split
(
":"
)
row
[
"frequency"
]
=
row
[
"frequency"
][
2
]
if
(
row
[
"frequency"
]
~=
nil
)
then
row
[
"frequency"
]
=
trim
(
row
[
"frequency"
])
end
end
-- get client/adhoc mode
if
wifiscan
:
match
(
"capability:"
)
then
row
[
"capability"
]
=
wifiscan
:
split
(
":"
)
row
[
"capability"
]
=
row
[
"capability"
][
2
]
if
(
row
[
"capability"
]
~=
nil
)
then
row
[
"capability"
]
=
trim
(
row
[
"capability"
])
end
end
-- get bssid
if
wifiscan
:
match
(
"(%w+:%w+:%w+:%w+:%w+:%w+)"
)
then
row
[
"bssid"
]
=
wifiscan
:
match
(
"(%w+:%w+:%w+:%w+:%w+:%w+)"
):
upper
()
end
-- get signal strength
if
wifiscan
:
match
(
"signal:"
)
then
row
[
"quality"
]
=
wifiscan
:
split
(
" "
)
row
[
"quality"
]
=
row
[
"quality"
][
2
]:
split
(
"."
)
if
row
[
"quality"
][
1
]:
match
(
"-"
)
then
row
[
"quality"
]
=
row
[
"quality"
][
1
]:
split
(
"-"
)
end
row
[
"quality"
]
=
tonumber
(
row
[
"quality"
][
2
]:
match
(
"(%d%d)"
))
end
end
end
end
table.sort
(
networks
,
function
(
a
,
b
)
return
a
[
"quality"
]
<
b
[
"quality"
]
end
)
return
networks
end
local
function
get_wlan_mesh_networks
(
wlan_list
)
local
mesh_wlan_list
=
{}
local
mesh_ssids
=
get_mesh_ssids
()
for
n
,
wlan
in
pairs
(
wlan_list
)
do
for
i
,
ssid
in
pairs
(
mesh_ssids
)
do
if
(
string.match
(
wlan
[
"ssid"
],
ssid
))
then
table.insert
(
mesh_wlan_list
,
wlan
)
break
end
end
end
return
mesh_wlan_list
end
-- this method removes the wireless network of the router itself
-- from the wlan_list
local
function
filter_my_wlan_network
(
wlan_list
)
local
filtered_wlan_list
=
{}
for
n
,
wlan
in
pairs
(
wlan_list
)
do
if
(
wlan
.
quality
~=
0
)
then
table.insert
(
filtered_wlan_list
,
wlan
)
end
end
return
filtered_wlan_list
end
local
function
filter_default_hood_wlan_networks
(
default_hood
,
wlan_list
)
local
filtered_wlan_list
=
{}
for
n
,
wlan
in
pairs
(
wlan_list
)
do
if
(
default_hood
.
bssid
~=
wlan
.
bssid
)
then
table.insert
(
filtered_wlan_list
,
wlan
)
end
end
return
filtered_wlan_list
end
-- bool if direct VPN
local
function
directVPN
()
local
function
directVPN
()
for
outgoingIF
in
io.open
(
"/sys/kernel/debug/batman_adv/bat0/originators"
,
'r'
):
lines
()
do
local
uci_vpn_net
=
uci
:
get
(
'fastd'
,
'mesh_vpn_backbone'
,
'net'
)
if
outgoingIF
:
match
(
string.gsub
(
"%[ "
..
uci
:
get
(
'fastd'
,
'mesh_vpn_backbone'
,
'net'
)
..
"%]"
,
"%_"
,
'-'
):
gsub
(
"%-"
,
"%%-"
))
then
local
uci_vpn_ifname
=
uci
:
get
(
'network'
,
uci_vpn_net
,
'ifname'
)
-- escape special chars "[]-"
uci_vpn_ifname
=
uci_vpn_ifname
:
gsub
(
"%-"
,
"%%-"
)
local
testString
=
'%[ '
..
uci_vpn_ifname
..
'%]'
for
outgoingIF
in
io.popen
(
string.format
(
"cat /sys/kernel/debug/batman_adv/bat0/originators"
),
'r'
):
lines
()
do
if
outgoingIF
:
match
(
testString
)
then
return
true
return
true
end
end
end
end
return
false
return
false
end
end
-- Retun a table of current peers from /etc/config/fastd
local
function
getCurrentPeers
()
local
configPeername
=
{}
local
configPeers
=
{}
uci
:
foreach
(
'fastd'
,
'peer'
,
function
(
s
)
if
s
[
'.name'
]
then
table.insert
(
configPeername
,
s
)
end
end
)
for
_
,
index
in
pairs
(
configPeername
)
do
for
prefix
,
peer
in
pairs
(
index
)
do
local
tmpPeer
=
{}
if
prefix
:
match
(
".name"
)
then
if
peer
:
match
(
"mesh_vpn_backbone_peer_"
)
then
local
tmpRemote
=
uci
:
get
(
'fastd'
,
peer
,
'remote'
)
tmpRemote
=
tmpRemote
[
1
]:
split
(
" "
)
local
remote
=
{}
remote
[
'host'
]
=
tmpRemote
[
1
]
remote
[
tmpRemote
[
2
]]
=
tmpRemote
[
3
]
tmpPeer
[
'key'
]
=
tostring
(
uci
:
get
(
'fastd'
,
peer
,
'key'
))
tmpPeer
[
'remote'
]
=
remote
configPeers
[
peer
]
=
tmpPeer
end
end
end
end
return
configPeers
end
-- Get Geoposition if no static position present try lwtrace. Return nil for no position
-- Get Geoposition if no static position present try lwtrace. Return nil for no position
local
function
getGeolocation
()
local
function
getGeolocation
()
local
lat
=
uci
:
get
(
'gluon-node-info'
,
uci
:
get_first
(
'gluon-node-info'
,
'location'
),
'latitude'
)
local
lat
=
uci
:
get
(
'gluon-node-info'
,
uci
:
get_first
(
'gluon-node-info'
,
'location'
),
'latitude'
)
...
@@ -97,10 +346,10 @@ local function getGeolocation()
...
@@ -97,10 +346,10 @@ local function getGeolocation()
if
string.find
(
scan
,
"(lat)"
)
then
if
string.find
(
scan
,
"(lat)"
)
then
local
last_val
=
nil
local
last_val
=
nil
for
geo
in
string.gmatch
(
scan
,
"[^%s]+"
)
do
for
geo
in
string.gmatch
(
scan
,
"[^%s]+"
)
do
if
geo
==
"
(lat)
"
then
if
geo
==
'
(lat)
'
then
lat
=
last_val
lat
=
last_val
end
end
if
geo
==
"
(lon)
"
then
if
geo
==
'
(lon)
'
then
lng
=
last_val
lng
=
last_val
end
end
last_val
=
geo
last_val
=
geo
...
@@ -126,141 +375,142 @@ local function getHoodByGeo(jhood,geo)
...
@@ -126,141 +375,142 @@ local function getHoodByGeo(jhood,geo)
return
nil
return
nil
end
end
-- reconfigures the bssid if needed
-- This method checks if the VPN configuration needs to be rewritten from the
-- returns true
-- hoodfile. Therefore the method performs 3 checks and returns false if all
-- returns false for error while setting bssid via UCI
-- checks fail. If one of the checks results to true the method returns true:
local
function
setHoodWifi
(
hoodBssid
,
radios
)
-- 1. Check if the local VPN configuratin has a server that does not exist
local
ret
=
true
-- in the hoodfile.
local
change
=
false
-- 2. Check if a server that does exist in the local VPN configuration AND
for
index
,
radio
in
ipairs
(
radios
)
do
-- in the hoodfile has a configuration change.
if
not
(
uci
:
get
(
'wireless'
,
'ibss_'
..
radio
,
'bssid'
)
==
hoodBssid
)
then
-- 3. Check if the hoodfile contains a server that does not exist in the
ret
=
uci
:
section
(
'wireless'
,
'wifi-iface'
,
'ibss_'
..
radio
,
-- local VPN configuration.
{
local
function
vpn_reconfiguration_needed
(
hood_serverlist
)
bssid
=
hoodBssid
local
local_serverlist
=
getCurrentPeers
()
}
)
-- Checks 1. and 2.
change
=
true
for
local_server_config_name
,
local_server
in
pairs
(
local_serverlist
)
do
end
local
local_server_exists_in_hoodfile
=
false
end
for
hood_server_index
,
hood_server
in
pairs
(
hood_serverlist
)
do
if
change
then
if
(
local_server_config_name
==
'mesh_vpn_backbone_peer_'
..
hood_server
[
"host"
]:
split
(
'.'
)[
1
])
then
uci
:
save
(
'wireless'
)
local_server_exists_in_hoodfile
=
true
uci
:
commit
(
'wireless'
)
if
(
local_server
.
key
~=
hood_server
[
'publickey'
]
)
then
os.execute
(
'wifi'
)
return
true
end
end
return
ret
local
hood_server_host
=
'
\"
'
..
hood_server
[
"host"
]
..
'
\"
'
if
(
local_server
.
remote
.
host
~=
hood_server_host
)
then
return
true
end
if
(
local_server
.
remote
.
port
~=
hood_server
[
'port'
]
)
then
return
true
end
end
end
if
not
(
local_server_exists_in_hoodfile
)
then
return
true
end
end
-- Check 3.
for
hood_server_index
,
hood_server
in
pairs
(
hood_serverlist
)
do
local
hood_server_exists_locally
=
false
for
local_server_config_name
,
local_server
in
pairs
(
local_serverlist
)
do
if
(
local_server_config_name
==
'mesh_vpn_backbone_peer_'
..
hood_server
[
"host"
]:
split
(
'.'
)[
1
])
then
hood_server_exists_locally
=
true
end
end
if
not
(
hood_server_exists_locally
)
then
return
true
end
end
return
false
end
end
-- Retun a table of current peers from /etc/config/fastd
-- Reconfigure fastd
local
function
getCurrentPeers
()
local
function
vpn_reconfigure
(
hood_serverlist
)
local
configPeername
=
{}
-- remove all servers
local
configPeers
=
{}
local
local_serverlist
=
getCurrentPeers
()
uci
:
foreach
(
'fastd'
,
'peer'
,
for
config_index
,
local_server
in
pairs
(
local_serverlist
)
do
function
(
s
)
uci
:
delete
(
'fastd'
,
config_index
)
if
s
[
'.name'
]
then
table.insert
(
configPeername
,
s
)
end
end
)
for
_
,
index
in
pairs
(
configPeername
)
do
for
prefix
,
peer
in
pairs
(
index
)
do
local
tmpPeer
=
{}
if
prefix
:
match
(
".name"
)
then
if
peer
:
match
(
"mesh_vpn_backbone_peer_"
)
then
local
tmpRemote
=
uci
:
get
(
'fastd'
,
peer
,
'remote'
)
tmpRemote
=
tmpRemote
[
1
]:
split
(
' '
)
local
remote
=
{}
remote
[
'host'
]
=
tmpRemote
[
1
]
remote
[
tmpRemote
[
2
]]
=
tmpRemote
[
3
]
tmpPeer
[
'key'
]
=
tostring
(
uci
:
get
(
'fastd'
,
peer
,
'key'
))
tmpPeer
[
'remote'
]
=
remote
configPeers
[
peer
]
=
tmpPeer
end
end
end
end
-- add servers from hoodfile
end
local
group
=
'mesh_vpn_backbone'
return
configPeers
for
i
,
hood_server
in
pairs
(
hood_serverlist
)
do
uci
:
section
(
'fastd'
,
'peer'
,
group
..
'_peer_'
..
hood_server
.
host
:
split
(
'.'
)[
1
],
{
enabled
=
1
,
net
=
'mesh_vpn'
,
group
=
group
,
key
=
hood_server
.
publickey
,
remote
=
{
'
\"
'
..
hood_server
.
host
..
'
\"
'
..
' port '
..
hood_server
.
port
}
}
)
end
uci
:
save
(
'fastd'
)
uci
:
commit
(
'fastd'
)
io.stderr
:
write
(
'Fastd needed reconfiguration. Stopped and applied new settings.\n'
)
end
-- Checks if wireless needs a reconfiguration. Returns true if any of the checks
-- passes. Otherwise the method returns false.
local
function
wireless_reconfiguration_needed
(
radios
,
hood_bssid
)
for
index
,
radio
in
ipairs
(
radios
)
do
if
(
uci
:
get
(
'wireless'
,
'ibss_'
..
radio
,
'bssid'
)
~=
hood_bssid
)
then
return
true
end
end
return
false
end
-- Reconfigure wireless
local
function
wireless_reconfigure
(
radios
,
hood_bssid
)
for
index
,
radio
in
ipairs
(
radios
)
do
if
not
(
uci
:
get
(
'wireless'
,
'ibss_'
..
radio
,
'bssid'
)
==
hood_bssid
)
then
uci
:
section
(
'wireless'
,
'wifi-iface'
,
'ibss_'
..
radio
,
{
bssid
=
hood_bssid
})
end
end
uci
:
save
(
'wireless'
)
uci
:
commit
(
'wireless'
)
end
end
-- This method sets a new
fastd
config and takes care that services are only
-- This method sets a new
hood
config and takes care that services are only
-- stopped or restarted if reconfiguration is needed.
-- stopped or restarted if reconfiguration is needed.
-- return true
-- Process:
-- return false for getting error while setting config via UCI
-- * Check if wireless needs reconfiguration and prepare reconfiguration
local
function
setHoodVPN
(
hood
)
-- * Check if fastd needs reconfiguration and prepare reconfiguration
local
change
=
false
-- * If fastd needs reconfiguration, stop fastd and apply new settings but
local
uciError
=
false
-- dont restart it before wireless has been reconfigured
local
configPeers
=
getCurrentPeers
()
-- * If wireless needs reconfiguration apply new settings and restart wireless
for
configIndex
,
configPeer
in
pairs
(
configPeers
)
do
-- * If fastd needed reconfiguration start fastd now
local
remove
=
true
local
function
set_hoodconfig
(
hood
,
radios
)
local
hoodserver0
=
nil
-- Check if VPN needs reconfiguration because in case of reconfiguration we
for
index0
,
serverlist
in
pairs
(
hood
.
servers
)
do
-- need to stop VPN before we can reconfigure any other connection.
for
index1
,
server
in
pairs
(
serverlist
)
do
local
vpn_reconfiguration_needed
=
vpn_reconfiguration_needed
(
hood
[
"servers"
]);
if
index1
:
match
(
"host"
)
then
if
(
vpn_reconfiguration_needed
)
then
local
hoodserver1
=
server
:
split
(
'.'
)
vpn_stop
()
if
configIndex
==
"mesh_vpn_backbone_peer_"
..
hoodserver1
[
1
]
then
remove
=
false
hoodserver0
=
index0
if
not
(
configPeer
.
key
==
serverlist
[
'publickey'
]
)
then
if
not
uci
:
set
(
'fastd'
,
configIndex
,
'key'
,
serverlist
[
'publickey'
])
then
uciError
=
true
end
change
=
true
end
server
=
'
\"
'
..
server
..
'
\"
'
if
not
(
configPeer
.
remote
.
host
==
server
)
then
local
hoodRemote
=
{}
table.insert
(
hoodRemote
,
server
..
' port '
..
configPeer
.
remote
.
port
)
if
not
uci
:
set
(
'fastd'
,
configIndex
,
'remote'
,
hoodRemote
)
then
uciError
=
true
end
change
=
true
end
if
not
(
configPeer
.
remote
.
port
==
serverlist
[
'port'
]
)
then
local
hoodRemote
=
{}
table.insert
(
hoodRemote
,
configPeer
.
remote
.
host
..
' port '
..
serverlist
[
'port'
])
if
not
uci
:
set
(
'fastd'
,
configIndex
,
'remote'
,
hoodRemote
)
then
uciError
=
true
end
change
=
true
end
end
end
end
end
end
-- reconfigure wireless
if
remove
then
if
(
wireless_reconfiguration_needed
(
radios
,
hood
[
"bssid"
]))
then
uci
:
delete
(
'fastd'
,
configIndex
)
wireless_reconfigure
(
radios
,
hood
[
"bssid"
])
change
=
true
wireless_restart
()
else
io.stderr
:
write
(
'Wireless needed reconfiguration. Applied new settings and restarted.\n'
)
if
hoodserver0
~=
nil
then
end
table.remove
(
hood
.
servers
,
hoodserver0
)
end
-- reconfigure fastd
end
if
(
vpn_reconfiguration_needed
)
then
end
vpn_reconfigure
(
hood
[
"servers"
])
for
index0
,
serverlist
in
pairs
(
hood
.
servers
)
do
-- scan mode can disable VPN so we need to make shure that VPN is enabled
local
group
=
'mesh_vpn_backbone'
-- if the router selects a hood
local
name
=
serverlist
.
host
:
split
(
'.'
)
vpn_enable
()
name
=
name
[
1
]
vpn_start
()
local
remote
=
{}
io.stderr
:
write
(
'VPN needed reconfiguration. Applied new settings and restarted.\n'
)
table.insert
(
remote
,
'
\"
'
..
serverlist
.
host
..
'
\"
'
..
' port '
..
serverlist
.
port
)
end
uci
:
section
(
'fastd'
,
'peer'
,
group
..
'_peer_'
..
name
,
io.stderr
:
write
(
"Set hood \""..hood["
name
"].."
\
"
\n
"
)
{
enabled
=
1
,
return
true
net
=
'mesh_vpn'
,
group
=
group
,
key
=
serverlist
.
publickey
,
remote
=
remote
}
)
change
=
true
end
if
change
then
uci
:
save
(
'fastd'
)
uci
:
commit
(
'fastd'
)
os.execute
(
'/etc/init.d/fastd restart 2> /dev/null'
)
end
if
uciError
then
return
false
end
return
true
end
end
-- Return the default hood in the hood list.
-- Return the default hood in the hood list.
...
@@ -276,77 +526,9 @@ local function getDefaultHood(jhood)
...
@@ -276,77 +526,9 @@ local function getDefaultHood(jhood)
return
nil
return
nil
end
end
-- This functions "Load bssid history" and "Save bssid history" will stored a
-- history list of tryed nighbour BSSIDs over the cron intervall
-- Load bssid history
local
function
bssid_hist_load
(
sfile
)
local
bssid_his
=
{}
local
sfileO
=
io.open
(
sfile
,
r
)
if
not
sfileO
then
return
bssid_his
end
for
line
in
sfileO
:
lines
()
do
if
line
:
match
(
"(%w+:%w+:%w+:%w+:%w+:%w+)"
)
then
table.insert
(
bssid_his
,
line
)
end
end
sfileO
:
close
()
return
bssid_his
end
-- Save bssid history
local
function
bssid_hist_save
(
tbl
,
filename
)
local
file
=
io.open
(
filename
,
"wb"
)
if
not
file
then
return
nil
end
for
idx
,
str
in
ipairs
(
tbl
)
do
file
:
write
(
str
)
end
file
:
close
()
end
-- Return the BSSID from the next freifunk router with the best signal quality and with has a difference to the actual used BSSID
local
function
getNeigbourBssid
(
radios
)
local
hoodbssid
=
nil
local
bssid_leases
=
bssid_hist_load
(
"/tmp/hoodselector.leases"
)
for
index
,
radio
in
ipairs
(
radios
)
do
hoodbssid
=
uci
:
get
(
'wireless'
,
'ibss_'
..
radio
,
'bssid'
)
local
bssid_his
=
''
if
bssid_leases
[
index
]
~=
nil
then
bssid_his
=
bssid_leases
[
index
]
end
bssid_his
=
bssid_his
..
' '
..
hoodbssid
local
lastQuality
=
255
local
tmphoodbssid
=
nil
for
wifiscan
in
io.popen
(
string.format
(
"iw %s scan | grep \"
%
s
\
" -B8"
,
uci
:
get
(
'wireless'
,
'ibss_'
..
radio
,
'ifname'
),
uci
:
get
(
'wireless'
,
'ibss_'
..
radio
,
'ssid'
)),
'r'
):
lines
()
do
if
wifiscan
:
match
(
"(%w+:%w+:%w+:%w+:%w+:%w+)"
)
then
tmphoodbssid
=
wifiscan
:
match
(
"(%w+:%w+:%w+:%w+:%w+:%w+)"
):
upper
()
end
if
wifiscan
:
match
(
"signal:"
)
then
local
quallity
=
wifiscan
:
split
(
' '
)
quallity
=
quallity
[
2
]:
split
(
'.'
)
if
quallity
[
1
]:
match
(
'-'
)
then
quallity
=
quallity
[
1
]:
split
(
'-'
)
end
quallity
=
tonumber
(
quallity
[
2
]:
match
(
"(%d%d)"
))
if
not
bssid_his
:
match
(
tmphoodbssid
)
then
if
(
lastQuality
>
quallity
)
then
lastQuality
=
quallity
hoodbssid
=
tmphoodbssid
end
end
end
end
if
(
lastQuality
==
255
)
then
bssid_his
=
''
end
bssid_leases
[
index
]
=
bssid_his
end
bssid_hist_save
(
bssid_leases
,
"/tmp/hoodselector.leases"
)
return
hoodbssid
end
-- boolean check if batman-adv has gateways
-- boolean check if batman-adv has gateways
local
function
getGwRange
()
local
function
batmanHasGateway
()
for
gw
in
io.open
(
"
/sys/kernel/debug/batman_adv/bat0/gateways"
,
'r'
):
lines
()
do
for
gw
in
io.
p
open
(
string.format
(
"cat
/sys/kernel/debug/batman_adv/bat0/gateways"
)
,
'r'
):
lines
()
do
if
gw
:
match
(
"Bit"
)
then
if
gw
:
match
(
"Bit"
)
then
return
true
return
true
end
end
...
@@ -364,73 +546,147 @@ local function gethoodByBssid(jhood, scan_bssid)
...
@@ -364,73 +546,147 @@ local function gethoodByBssid(jhood, scan_bssid)
return
nil
return
nil
end
end
--Start
local
function
get_batman_mesh_network
(
sorted_wlan_list
,
defaultHood
)
--Read hoods json file
io.stderr
:
write
(
'Testing neighboring adhoc networks for batman advanced gw connection.\n'
)
io.stderr
:
write
(
'The following wireless networks have been found:\n'
)
for
n
,
network
in
pairs
(
sorted_wlan_list
)
do
print
(
network
[
"quality"
]
..
"
\t
"
..
network
[
"frequency"
]
..
"
\t
"
..
network
[
"bssid"
]
..
"
\t
"
..
network
[
"ssid"
])
end
-- we only want to test adhoc networks with freifunk ssid
sorted_wlan_list
=
get_wlan_mesh_networks
(
sorted_wlan_list
)
-- we dont want to get tricked by our our signal
sorted_wlan_list
=
filter_my_wlan_network
(
sorted_wlan_list
)
-- we dont want to test the default hood because if there is no other
-- hood present we will connect to the default hood anyway
sorted_wlan_list
=
filter_default_hood_wlan_networks
(
defaultHood
,
sorted_wlan_list
)
io.stderr
:
write
(
'After filtering we will test the following wireless networks:\n'
)
for
n
,
network
in
pairs
(
sorted_wlan_list
)
do
print
(
network
[
"quality"
]
..
"
\t
"
..
network
[
"frequency"
]
..
"
\t
"
..
network
[
"bssid"
]
..
"
\t
"
..
network
[
"ssid"
])
end
local
bssid
=
nil
if
(
next
(
sorted_wlan_list
))
then
io.stderr
:
write
(
"Prepare configuration for testing wireless networks...\n"
)
-- Notice:
-- we will use iw for testing the wireless networks because using iw does
-- not need any changes inside the uci config. This approach allows the
-- router to automatically reset to previous configuration in case
-- someone disconnects the router from power during test.
-- stop vpn to prevent two hoods from beeing connected in case
-- the router gets internet unexpectedly during test.
vpn_stop
()
-- remove the ap network because we cannot change
-- the settings of the adhoc network if the ap network is still operating
os.execute
(
"iw dev client0 del"
)
for
n
,
wireless
in
pairs
(
sorted_wlan_list
)
do
io.stderr
:
write
(
"Testing "
..
wireless
[
"bssid"
]
..
"..."
)
-- leave the current adhoc network
os.execute
(
"iw dev ibss0 ibss leave"
)
-- setup the adhoc network we want to test
os.execute
(
"iw dev ibss0 ibss join "
..
wireless
[
"ssid"
]
..
" "
..
wireless
[
"frequency"
]
..
" "
..
wireless
[
"bssid"
])
-- sleep 30 seconds till the connection is fully setup
sleep
(
30
)
-- os.execute("logread")
-- os.execute("batctl o")
if
batmanHasGateway
()
then
bssid
=
wireless
[
"bssid"
]
break
;
end
end
vpn_start
()
wireless_restart
()
io.stderr
:
write
(
"Finished testing wireless networks, restored previous configuration\n"
)
end
return
bssid
end
-- INITIALIZE AND PREPARE DATA --
-- read hoodfile, exit if reading the hoodfile fails
local
jhood
=
readHoodfile
(
file
)
local
jhood
=
readHoodfile
(
file
)
if
jhood
==
nil
then
if
jhood
==
nil
then
io.stderr
:
write
(
"
There seems to have gone something wrong while reading hoodfile from
"
..
file
..
'
\n
'
)
io.stderr
:
write
(
'
There seems to have gone something wrong while reading hoodfile from
'
..
file
..
'
\n
'
)
exit
()
exit
()
end
end
-- check if a default hood has been defined and exit if none has been defined
local
defaultHood
=
getDefaultHood
(
jhood
)
if
defaultHood
==
nil
then
io.stderr
:
write
(
'No defaulthood defined.\n'
)
exit
()
end
-- Get list of wifi devices
-- Get list of wifi devices
local
radios
=
getWifiDevices
()
local
radios
=
getWifiDevices
()
--If direct vpn, sed hood by geo.
-- VPN MODE
-- If we have a VPN connection then we will try to get the routers location and
-- select the hood coresponding to our location.
-- If no hood for the location has been defined, we will select
-- the default hood.
-- If we can not get our routers location, we will fallback to scan mode.
if
directVPN
()
then
if
directVPN
()
then
io.stderr
:
write
(
'VPN connection found.\n'
)
local
geo
=
getGeolocation
()
local
geo
=
getGeolocation
()
if
geo
[
1
]
~=
nil
and
geo
[
2
]
~=
nil
then
if
geo
[
1
]
~=
nil
and
geo
[
2
]
~=
nil
then
io.stderr
:
write
(
'Position found.\n'
)
local
geoHood
=
getHoodByGeo
(
jhood
,
geo
)
local
geoHood
=
getHoodByGeo
(
jhood
,
geo
)
if
geoHood
~=
nil
then
if
geoHood
~=
nil
then
if
setHoodWifi
(
geoHood
.
bssid
,
radios
)
and
setHoodVPN
(
geoHood
)
then
set_hoodconfig
(
geoHood
,
radios
)
io.stderr
:
write
(
'Setting hood getting from position.\n'
)
io.stderr
:
write
(
'Hood set by VPN mode.\n'
)
exit
()
end
io.stderr
:
write
(
'Error while setting new hood getting by geoposition.\n'
)
exit
()
end
io.stderr
:
write
(
'No hood has been defined for current position.\n'
)
local
defaultHood
=
getDefaultHood
(
jhood
)
if
defaultHood
~=
nil
then
if
setHoodWifi
(
defaultHood
.
bssid
,
radios
)
and
setHoodVPN
(
defaultHood
)
then
io.stderr
:
write
(
'Setting defaulthood.\n'
)
exit
()
end
io.stderr
:
write
(
'Error while setting defaulthood.\n'
)
exit
()
exit
()
end
end
io.stderr
:
write
(
'No hood has been defined for current position.\n'
)
set_hoodconfig
(
defaultHood
,
radios
)
io.stderr
:
write
(
'Defaulthood set.\n'
)
exit
()
end
end
io.stderr
:
write
(
'Router dont have a position.\n'
)
io.stderr
:
write
(
'No position found\n'
)
else
io.stderr
:
write
(
'No VPN connection found\n'
)
end
end
if
next
(
radios
)
then
if
batmanHasGateway
()
then
-- If no direct VPN and batman GWs not in range set scanned bssid
io.stderr
:
write
(
'Batman gateways found, everything seems to be ok - doing nothing\n'
)
local
scanBssid
=
getNeigbourBssid
(
radios
)
exit
()
if
scanBssid
~=
nil
then
end
if
not
getGwRange
()
then
if
setHoodWifi
(
scanBssid
,
radios
)
then
io.stderr
:
write
(
'Setting Bssid getting from Scan.\n'
)
else
io.stderr
:
write
(
'Error while setting Bssid getting from Scan.\n'
)
exit
()
end
end
-- Set VPN config getting by BSSID
-- SCAN MODE
local
bssidHood
=
gethoodByBssid
(
jhood
,
scanBssid
)
if
next
(
radios
)
then
-- check if there exist a neighboring freifunk batman advanced mesh
-- network with an active connection to a batman advanced gateway
local
sortedWlanList
=
wlan_list_sorted
(
radios
)
local
meshBSSID
=
get_batman_mesh_network
(
sortedWlanList
,
defaultHood
)
if
meshBSSID
~=
nil
then
io.stderr
:
write
(
"Neighoring freifunk batman advanced mesh with BSSID "
..
meshBSSID
..
" found\n"
)
local
bssidHood
=
gethoodByBssid
(
jhood
,
meshBSSID
)
if
bssidHood
~=
nil
then
if
bssidHood
~=
nil
then
if
setHoodVPN
(
bssidHood
)
then
set_hoodconfig
(
bssidHood
,
radios
)
io.stderr
:
write
(
'Setting hood getting from bssid.\n'
)
io.stderr
:
write
(
'Hood set by scan mode\n'
)
os.execute
(
'/etc/init.d/fastd start 2> /dev/null'
)
os.execute
(
'/etc/init.d/fastd enable'
)
exit
()
end
io.stderr
:
write
(
'Error while setting new hood getting by bssid.\n'
)
exit
()
exit
()
end
end
io.stderr
:
write
(
'No hood has been defined for scanned bssid.\n'
)
os.execute
(
'/etc/init.d/fastd stop 2> /dev/null'
)
-- if the bssid does not corespond to any hood, we disable vpn and
os.execute
(
'/etc/init.d/fastd disable'
)
-- just establish a wireless connection to the mesh without any vpn or
-- mesh on lan (TODO) connectivity
vpn_stop
()
vpn_disable
()
wireless_reconfigure
(
radios
,
meshBSSID
)
wireless_restart
()
io.stderr
:
write
(
'Could not select a hood but established a connection via wireless mesh.\n'
)
io.stderr
:
write
(
'Disabled all connections except connections via wireless mesh.\n'
)
exit
()
exit
()
end
end
io.stderr
:
write
(
'
Error while scanning wifi
.\n'
)
io.stderr
:
write
(
'
No neighboring freifunk batman advanced mesh found
.\n'
)
end
end
-- DEFAULT-HOOD MODE
-- If we do NOT have a VPN connection AND found no freifunk mesh network while
-- scanning then we set the default hood
set_hoodconfig
(
defaultHood
,
radios
)
io.stderr
:
write
(
'Set defaulthood.\n'
)
exit
()
exit
()
This diff is collapsed.
Click to expand it.
Preview
0%
Loading
Try again
or
attach a new file
.
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Save comment
Cancel
Please
register
or
sign in
to comment