api: revise localhost function (#128)

* api: revise localhost function

Revise getLocalHosts() so it doesn't report unwanted hosts.  
getLocalCnxType() is no longer needed.

* include new iplookup function too

* incorporate Eric r1de values for getCurrentNeighbors

* use alternative for mac2host()

* get actual wlan interface for arp query

* tested on dualband radio

Tested on dualband radios with active clients on both Mesh RF and Wifi 
AP.

* add more error checking

* fix iplookup match

It is possible to have 2-digit "mid" prefixes. Fixes match to account 
for 2 possible digits.

* tighten up code

* add extra info values for Eric r1de
This commit is contained in:
Steve AB7PA 2021-07-10 10:39:25 -07:00 committed by GitHub
parent 7fa6b57e1c
commit a7ab2c6a46
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 98 additions and 88 deletions

View File

@ -513,53 +513,31 @@ function model.getCurrentDHCPLeases()
return leases return leases
end end
-------------------------------------
-- Returns Local Host Connection Type
-------------------------------------
function model.getLocalCnxType(hostname)
if string.match(hostname,"localhost") then
return "Loopback"
elseif string.match(hostname,"dtdlink") then
return "DTD"
elseif hostname:lower() == string.lower( model.getNodeName() ) then
return "RF"
else
return "LAN"
end
end
------------------------------------- -------------------------------------
-- Returns Local Hosts -- Returns Local Hosts
------------------------------------- -------------------------------------
function model.getLocalHosts() function model.getLocalHosts()
local hosts, line local localhosts = {}
if nixio.fs.access("/etc/hosts") then myhosts=os.capture('/bin/grep "# myself" /var/run/hosts_olsr|grep -v dtdlink')
for line in io.lines("/etc/hosts") do local lines = myhosts:splitNewLine()
local data = line:match("^([^#;]+)[#;]*(.*)$") -- line is not a comment data = {}
if data then for k,v in pairs(lines) do
local hostname, entries data = v:splitWhiteSpace()
local ip, entries = data:match("^%s*([%[%]%x%.%:]+)%s+(%S.-%S)%s*$") local ip = data[1]
local hostname = data[2]
if ip then if ip and hostname then
local entry = { local entry = {}
["ip"] = ip, entry['ip'] = ip
["hostnames"] = { }, entry['hostname'] = hostname
["cnxtype"] = "" if hostname:lower() == string.lower( model.getNodeName() ) then
} entry['cnxtype'] = "RF"
local index = 0 else
for hostname in entries:gmatch("%S+") do entry['cnxtype'] = "LAN"
hostname = string.gsub(hostname,".local.mesh$","") end
entry["cnxtype"] = model.getLocalCnxType(hostname) table.insert(localhosts, entry)
entry["hostnames"][index] = hostname end
index = index + 1 end
end return localhosts
hosts = hosts or { }
hosts[#hosts+1] = entry
end
end
end
end
return hosts
end end
------------------------------------- -------------------------------------

View File

@ -68,58 +68,77 @@ function model.getCurrentNeighbors(RFinfo)
local info={} local info={}
local links=model.getOLSRLinks() -- Get info for all current neighbors local links=model.getOLSRLinks() -- Get info for all current neighbors
for k,v in pairs(links) do for k,v in pairs(links) do
local host local host=nslookup(v['remoteIP'])
local linkip=v['remoteIP'] if host then
local mainip=iplookup(host)
if mainip then
info[mainip]={}
info[linkip]={} if host~=nil then
info[linkip]['olsrInterface']=v['olsrInterface'] host = string.gsub(host,"mid%d+.", "")
info[linkip]['linkType']= model.getOLSRInterfaceType(v['olsrInterface']) -- RF or DTD or TUN host = string.gsub(host,"dtdlink%.", "")
info[linkip]['linkQuality']=v['linkQuality'] host = string.gsub(host,".local.mesh$","")
info[linkip]['neighborLinkQuality']=v['neighborLinkQuality'] info[mainip]['hostname']=host
else
info[mainip]['hostname']=mainip
end
local linkhost=nslookup(linkip) -- TOTO: stop using nslookup? use /var/run/olsr_hosts info[mainip]['olsrInterface']=v['olsrInterface']
if linkhost~=nil then info[mainip]['linkType']= model.getOLSRInterfaceType(v['olsrInterface']) -- RF or DTD or TUN
host = string.gsub(linkhost,"mid%d+.", "") info[mainip]['linkQuality']=v['linkQuality']
host = string.gsub(host,"dtdlink%.", "") info[mainip]['neighborLinkQuality']=v['neighborLinkQuality']
host = string.gsub(host,".local.mesh$","")
info[linkip]['hostname']=host
else
info[linkip]['hostname']=linkip
end
if info[linkip]['linkType'] == "RF" and RFinfo then -- get additional info for RF link -- additional info about each link
require("iwinfo") info[mainip]['validityTime']=v['validityTime']
info[linkip]["rfip"] = linkip info[mainip]['symmetryTime']=v['symmetryTime']
local radio = ai.getMeshRadioDevice() info[mainip]['asymmetryTime']=v['asymmetryTime']
local bandwidth = tonumber(ai.getChannelBW(radio)) info[mainip]['vtime']=v['vtime']
local wlan=get_ifname('wifi') info[mainip]['currentLinkStatus']=v['currentLinkStatus']
local RFneighbors=iwinfo['nl80211'].assoclist(wlan) info[mainip]['previousLinkStatus']=v['previousLinkStatus']
local mac2node=mac2host() info[mainip]['hysteresis']=v['hysteresis']
for i, mac_host in pairs(mac2node) do info[mainip]['pending']=v['pending']
local mac=string.match(mac_host, "^(.-)\-") info[mainip]['lostLinkTime']=v['lostLinkTime']
mac=mac:upper() info[mainip]['helloTime']=v['helloTime']
local node=string.match(mac_host, "\-(.*)") -- add error checking here? info[mainip]['lastHelloTime']=v['lastHelloTime']
if node == "" then node=linkhost end info[mainip]['seqnoValid']=v['seqnoValid']
if linkhost == node or linkip == node then info[mainip]['seqno']=v['seqno']
for stn in pairs(RFneighbors) do info[mainip]['lossHelloInterval']=v['lossHelloInterval']
stnInfo=iwinfo['nl80211'].assoclist(wlan)[mac] info[mainip]['lossTime']=v['lossTime']
if stnInfo ~= nil then info[mainip]['lossMultiplier']=v['lossMultiplier']
info[linkip]["signal"]=tonumber(stnInfo.signal) info[mainip]['linkCost']=v['linkCost']
info[linkip]["noise"]=tonumber(stnInfo.noise)
info[linkip]["tx_rate"]=adjust_rate(stnInfo.tx_rate/1000,bandwidth) if info[mainip]['linkType'] == "RF" and RFinfo then
info[linkip]["rx_rate"]=adjust_rate(stnInfo.rx_rate/1000,bandwidth) require("iwinfo")
info[linkip]["expected_throughput"]=adjust_rate(stnInfo.expected_throughput/1000,bandwidth) local radio = ai.getMeshRadioDevice()
local bandwidth = tonumber(ai.getChannelBW(radio))
local RFinterface=get_ifname('wifi')
local arptable=capture("/bin/cat /proc/net/arp |grep "..RFinterface)
local lines=arptable:splitNewLine()
table.remove(lines, #lines) -- remove blank last line
for k1,v1 in pairs(lines) do
local field=v1:splitWhiteSpace()
local arpip=field[1]
local mac=field[4]
mac=mac:upper()
if mac and arpip == mainip then
stnInfo=iwinfo['nl80211'].assoclist(RFinterface)[mac]
if stnInfo~=nil then
info[mainip]["signal"]=tonumber(stnInfo.signal)
info[mainip]["noise"]=tonumber(stnInfo.noise)
if stnInfo.tx_rate then
info[mainip]["tx_rate"]=adjust_rate(stnInfo.tx_rate/1000,bandwidth)
end
if stnInfo.rx_rate then
info[mainip]["rx_rate"]=adjust_rate(stnInfo.rx_rate/1000,bandwidth)
end
if stnInfo.expected_throughput then
info[mainip]["expected_throughput"]=adjust_rate(stnInfo.expected_throughput/1000,bandwidth)
end
end
end end
end end
end end
end end
else -- Get RF IP for non-RF nodes to display services keyed to RF IP
local allhosts=ai.all_hosts()
for k,v in pairs(allhosts) do
if linkhost == v['name'] or host == v['name'] then
info[linkip]["rfip"]=v['ip']
end
end
end end
end end
return info return info

View File

@ -257,6 +257,19 @@ function nslookup(ip)
end end
end end
-------------------------------------
-- Returns first IP of given host
-------------------------------------
function iplookup(host)
if host:find("dtd.*%.") or host:find("mid%d+%.") then
host=host:match("%.(.*)")
end
local nso=capture("nslookup "..host)
local ip=nso:match("Address 1: (.*)%c")
return ip
end
------------------------------------- -------------------------------------
-- Returns traceroute -- Returns traceroute
------------------------------------- -------------------------------------