Merge pull request #990 from freifunk-ffm/christf_get_mesh_interfaces
gluon-core: add function to gluon.util that returns all active mesh-devices
This commit is contained in:
commit
2ddf77fc81
@ -1,25 +1,25 @@
|
|||||||
-- Writes all lines from the file input to the file output except those starting with prefix
|
-- Writes all lines from the file input to the file output except those starting with prefix
|
||||||
-- Doesn't close the output file, but returns the file object
|
-- Doesn't close the output file, but returns the file object
|
||||||
local function do_filter_prefix(input, output, prefix)
|
local function do_filter_prefix(input, output, prefix)
|
||||||
local f = io.open(output, 'w+')
|
local f = io.open(output, 'w+')
|
||||||
local l = prefix:len()
|
local l = prefix:len()
|
||||||
|
|
||||||
for line in io.lines(input) do
|
for line in io.lines(input) do
|
||||||
if line:sub(1, l) ~= prefix then
|
if line:sub(1, l) ~= prefix then
|
||||||
f:write(line, '\n')
|
f:write(line, '\n')
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
return f
|
return f
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
local function escape_args(ret, arg0, ...)
|
local function escape_args(ret, arg0, ...)
|
||||||
if not arg0 then
|
if not arg0 then
|
||||||
return ret
|
return ret
|
||||||
end
|
end
|
||||||
|
|
||||||
return escape_args(ret .. "'" .. string.gsub(arg0, "'", "'\\''") .. "' ", ...)
|
return escape_args(ret .. "'" .. string.gsub(arg0, "'", "'\\''") .. "' ", ...)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
@ -38,79 +38,88 @@ local uci = require('luci.model.uci').cursor()
|
|||||||
local lutil = require 'luci.util'
|
local lutil = require 'luci.util'
|
||||||
local fs = require 'nixio.fs'
|
local fs = require 'nixio.fs'
|
||||||
|
|
||||||
|
|
||||||
module 'gluon.util'
|
module 'gluon.util'
|
||||||
|
|
||||||
function exec(...)
|
function exec(...)
|
||||||
return os.execute(escape_args('', 'exec', ...))
|
return os.execute(escape_args('', 'exec', ...))
|
||||||
end
|
end
|
||||||
|
|
||||||
-- Removes all lines starting with a prefix from a file, optionally adding a new one
|
-- Removes all lines starting with a prefix from a file, optionally adding a new one
|
||||||
function replace_prefix(file, prefix, add)
|
function replace_prefix(file, prefix, add)
|
||||||
local tmp = file .. '.tmp'
|
local tmp = file .. '.tmp'
|
||||||
local f = do_filter_prefix(file, tmp, prefix)
|
local f = do_filter_prefix(file, tmp, prefix)
|
||||||
if add then
|
if add then
|
||||||
f:write(add)
|
f:write(add)
|
||||||
end
|
end
|
||||||
f:close()
|
f:close()
|
||||||
os.rename(tmp, file)
|
os.rename(tmp, file)
|
||||||
end
|
end
|
||||||
|
|
||||||
function readline(fd)
|
function readline(fd)
|
||||||
local line = fd:read('*l')
|
local line = fd:read('*l')
|
||||||
fd:close()
|
fd:close()
|
||||||
return line
|
return line
|
||||||
end
|
end
|
||||||
|
|
||||||
function lock(file)
|
function lock(file)
|
||||||
exec('lock', file)
|
exec('lock', file)
|
||||||
end
|
end
|
||||||
|
|
||||||
function unlock(file)
|
function unlock(file)
|
||||||
exec('lock', '-u', file)
|
exec('lock', '-u', file)
|
||||||
end
|
end
|
||||||
|
|
||||||
function node_id()
|
function node_id()
|
||||||
return string.gsub(sysconfig.primary_mac, ':', '')
|
return string.gsub(sysconfig.primary_mac, ':', '')
|
||||||
end
|
end
|
||||||
|
|
||||||
|
function get_mesh_devices(uconn)
|
||||||
|
local dump = uconn:call("network.interface", "dump", {})
|
||||||
|
local devices = {}
|
||||||
|
for _, interface in ipairs(dump.interface) do
|
||||||
|
if ( (interface.proto == "gluon_mesh") and interface.up ) then
|
||||||
|
table.insert(devices, interface.device)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
return devices
|
||||||
|
end
|
||||||
|
|
||||||
local function find_phy_by_path(path)
|
local function find_phy_by_path(path)
|
||||||
for phy in fs.glob('/sys/devices/' .. path .. '/ieee80211/phy*') do
|
for phy in fs.glob('/sys/devices/' .. path .. '/ieee80211/phy*') do
|
||||||
return phy:match('([^/]+)$')
|
return phy:match('([^/]+)$')
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
local function find_phy_by_macaddr(macaddr)
|
local function find_phy_by_macaddr(macaddr)
|
||||||
local addr = macaddr:lower()
|
local addr = macaddr:lower()
|
||||||
for file in fs.glob('/sys/class/ieee80211/*/macaddress') do
|
for file in fs.glob('/sys/class/ieee80211/*/macaddress') do
|
||||||
if lutil.trim(fs.readfile(file)) == addr then
|
if lutil.trim(fs.readfile(file)) == addr then
|
||||||
return file:match('([^/]+)/macaddress$')
|
return file:match('([^/]+)/macaddress$')
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
local function find_phy(radio)
|
local function find_phy(radio)
|
||||||
local config = uci:get_all('wireless', radio)
|
local config = uci:get_all('wireless', radio)
|
||||||
|
|
||||||
if not config or config.type ~= 'mac80211' then
|
if not config or config.type ~= 'mac80211' then
|
||||||
return nil
|
return nil
|
||||||
elseif config.path then
|
elseif config.path then
|
||||||
return find_phy_by_path(config.path)
|
return find_phy_by_path(config.path)
|
||||||
elseif config.macaddr then
|
elseif config.macaddr then
|
||||||
return find_phy_by_macaddr(config.macaddr)
|
return find_phy_by_macaddr(config.macaddr)
|
||||||
else
|
else
|
||||||
return nil
|
return nil
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
local function get_addresses(radio)
|
local function get_addresses(radio)
|
||||||
local phy = find_phy(radio)
|
local phy = find_phy(radio)
|
||||||
if not phy then
|
if not phy then
|
||||||
return function() end
|
return function() end
|
||||||
end
|
end
|
||||||
|
|
||||||
return io.lines('/sys/class/ieee80211/' .. phy .. '/addresses')
|
return io.lines('/sys/class/ieee80211/' .. phy .. '/addresses')
|
||||||
end
|
end
|
||||||
|
|
||||||
-- Generates a (hopefully) unique MAC address
|
-- Generates a (hopefully) unique MAC address
|
||||||
@ -126,70 +135,70 @@ end
|
|||||||
-- 6: ibss1
|
-- 6: ibss1
|
||||||
-- 7: wan_radio1 (private WLAN); mesh VPN
|
-- 7: wan_radio1 (private WLAN); mesh VPN
|
||||||
function generate_mac(i)
|
function generate_mac(i)
|
||||||
if i > 7 or i < 0 then return nil end -- max allowed id (0b111)
|
if i > 7 or i < 0 then return nil end -- max allowed id (0b111)
|
||||||
|
|
||||||
local hashed = string.sub(hash.md5(sysconfig.primary_mac), 0, 12)
|
local hashed = string.sub(hash.md5(sysconfig.primary_mac), 0, 12)
|
||||||
local m1, m2, m3, m4, m5, m6 = string.match(hashed, '(%x%x)(%x%x)(%x%x)(%x%x)(%x%x)(%x%x)')
|
local m1, m2, m3, m4, m5, m6 = string.match(hashed, '(%x%x)(%x%x)(%x%x)(%x%x)(%x%x)(%x%x)')
|
||||||
|
|
||||||
m1 = tonumber(m1, 16)
|
m1 = tonumber(m1, 16)
|
||||||
m6 = tonumber(m6, 16)
|
m6 = tonumber(m6, 16)
|
||||||
|
|
||||||
m1 = nixio.bit.bor(m1, 0x02) -- set locally administered bit
|
m1 = nixio.bit.bor(m1, 0x02) -- set locally administered bit
|
||||||
m1 = nixio.bit.band(m1, 0xFE) -- unset the multicast bit
|
m1 = nixio.bit.band(m1, 0xFE) -- unset the multicast bit
|
||||||
|
|
||||||
-- It's necessary that the first 45 bits of the MAC address don't
|
-- It's necessary that the first 45 bits of the MAC address don't
|
||||||
-- vary on a single hardware interface, since some chips are using
|
-- vary on a single hardware interface, since some chips are using
|
||||||
-- a hardware MAC filter. (e.g 'rt305x')
|
-- a hardware MAC filter. (e.g 'rt305x')
|
||||||
|
|
||||||
m6 = nixio.bit.band(m6, 0xF8) -- zero the last three bits (space needed for counting)
|
m6 = nixio.bit.band(m6, 0xF8) -- zero the last three bits (space needed for counting)
|
||||||
m6 = m6 + i -- add virtual interface id
|
m6 = m6 + i -- add virtual interface id
|
||||||
|
|
||||||
return string.format('%02x:%s:%s:%s:%s:%02x', m1, m2, m3, m4, m5, m6)
|
return string.format('%02x:%s:%s:%s:%s:%02x', m1, m2, m3, m4, m5, m6)
|
||||||
end
|
end
|
||||||
|
|
||||||
local function get_wlan_mac_from_driver(radio, vif)
|
local function get_wlan_mac_from_driver(radio, vif)
|
||||||
local primary = sysconfig.primary_mac:lower()
|
local primary = sysconfig.primary_mac:lower()
|
||||||
|
|
||||||
local i = 1
|
local i = 1
|
||||||
for addr in get_addresses(radio) do
|
for addr in get_addresses(radio) do
|
||||||
if addr:lower() ~= primary then
|
if addr:lower() ~= primary then
|
||||||
if i == vif then
|
if i == vif then
|
||||||
return addr
|
return addr
|
||||||
end
|
end
|
||||||
|
|
||||||
i = i + 1
|
i = i + 1
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
function get_wlan_mac(radio, index, vif)
|
function get_wlan_mac(radio, index, vif)
|
||||||
local addr = get_wlan_mac_from_driver(radio, vif)
|
local addr = get_wlan_mac_from_driver(radio, vif)
|
||||||
if addr then
|
if addr then
|
||||||
return addr
|
return addr
|
||||||
end
|
end
|
||||||
|
|
||||||
return generate_mac(4*(index-1) + (vif-1))
|
return generate_mac(4*(index-1) + (vif-1))
|
||||||
end
|
end
|
||||||
|
|
||||||
-- Iterate over all radios defined in UCI calling
|
-- Iterate over all radios defined in UCI calling
|
||||||
-- f(radio, index, site.wifiX) for each radio found while passing
|
-- f(radio, index, site.wifiX) for each radio found while passing
|
||||||
-- site.wifi24 for 2.4 GHz devices and site.wifi5 for 5 GHz ones.
|
-- site.wifi24 for 2.4 GHz devices and site.wifi5 for 5 GHz ones.
|
||||||
function iterate_radios(f)
|
function iterate_radios(f)
|
||||||
local radios = {}
|
local radios = {}
|
||||||
|
|
||||||
uci:foreach('wireless', 'wifi-device',
|
uci:foreach('wireless', 'wifi-device',
|
||||||
function(s)
|
function(s)
|
||||||
table.insert(radios, s['.name'])
|
table.insert(radios, s['.name'])
|
||||||
end
|
end
|
||||||
)
|
)
|
||||||
|
|
||||||
for index, radio in ipairs(radios) do
|
for index, radio in ipairs(radios) do
|
||||||
local hwmode = uci:get('wireless', radio, 'hwmode')
|
local hwmode = uci:get('wireless', radio, 'hwmode')
|
||||||
|
|
||||||
if hwmode == '11g' or hwmode == '11ng' then
|
if hwmode == '11g' or hwmode == '11ng' then
|
||||||
f(radio, index, site.wifi24)
|
f(radio, index, site.wifi24)
|
||||||
elseif hwmode == '11a' or hwmode == '11na' then
|
elseif hwmode == '11a' or hwmode == '11na' then
|
||||||
f(radio, index, site.wifi5)
|
f(radio, index, site.wifi5)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
Loading…
Reference in New Issue
Block a user