local n={}local o=pairs
local w=ipairs
local h=tonumber
local t=string
local I=type
local e=require("transformer.mapper.ucihelper")local i=require("transformer.mapper.ubus").connect()local y=require("transformer.shared.dhcp")local x=require("bit")local A=require("math")local _=require("tch.posix")local m=require("io")local a={config="dhcp"}local D={config="ethernet",sectionname="mapping"}local f={config="firewall",sectionname="zone"}local d={config="network"}local b={config="wireless"}local u={}local T=_.AF_INET
local v={}local k=m.open
local g=t.lower(e.get_from_uci({config="env",sectionname="var",option="qtn_eth_mac"}))local C=t.lower(e.get_from_uci({config="env",sectionname="var",option="local_eth_mac_lxc"}))local s,S,P=t.match,t.find,t.sub
local l,r,c,p
function n.firewallZones()local t={}e.foreach_on_uci(f,function(n)if I(n.network)~="table"then
n.network={n.network}end
t[n.name or n['.name']]=n
end)return t
end
local f=n.firewallZones
function n.firewallZoneForInterface(e,n)n=n or f()for t,n in o(n)do
for a,t in w(n.network)do
if t==e then
return n
end
end
end
end
local function w(e)local n={}local t=e=="wan"for a,e in o(f())do
local a=e.wan=="1"if a==t then
for t,e in o(e.network)do
n[e]=true
end
end
end
return n
end
local function H(n)if n["state"]=="disconnected"or n["technology"]=="wireless"or n["technology"]=="ethernet"then
return true
end
end
local function M(n)return n%(2^32)end
local function f(n)local n=_.inet_pton(T,n)if n then
local a,e,t,n=n:byte(1,4)return(a*(256^3))+(e*(256^2))+(t*256)+n
end
end
local function T(n)d.sectionname=n
local n=e.getall_from_uci(d)or{}local e=n.ipaddr and f(n.ipaddr)local n=n.netmask and f(n.netmask)if e and n then
return M(x.band(e,n))end
end
local function _(i,l,t,n,o)local r=A.min(t+n-1,o)local o=0
a.sectionname="dhcp"e.foreach_on_uci(a,function(n)if n[".name"]~=l and n.interface then
local e=T(n.interface)if e and e==i and n.start and n.limit then
n.start=h(n.start)n.limit=h(n.limit)if(t>=n.start and t<(n.start+n.limit))or(r>=n.start and r<(n.limit+n.start))then
o=1
return false
end
if t<n.start and r>(n.limit+n.start)then
o=1
return false
end
end
end
end)if o==1 then
return nil,"The specified range overlaps an existing range."end
return true
end
local function d(t,e,n)local e=i:call(t,e,{name=n})or{}return e[n]or{}end
function n.getWanInterfaces()return w("wan")end
function n.getLanInterfaces()return w("lan")end
function n.getHostDataByMAC(e)local n=i:call("hostmanager.device","get",{})or{}for t,n in o(n)do
if n and n["mac-address"]==e then
return n,t
end
end
return{},""end
function n.getHostInfo(a,t)local e={}local a=a or i:call("hostmanager.device","get",v)or v
local r=n.getLanInterfaces()for a,n in o(a)do
if r[n.interface]and n["mac-address"]~=g and n["mac-address"]~=C and H(n)then
e[#e+1]=t and t(n)or a
end
end
return e
end
function n.triggerACSRescan(n,e)local e=h(e)or 0
if n then
i:call("wireless.radio.acs","rescan",{name=n,act=e})else
i:call("wireless.radio.acs","rescan",{})end
end
function n.listContains(e,n)for t,e in o(e)do
if n==e then
return true
end
end
end
function n.setDHCPMinAddress(o,n,r)local t=f(n)if not t then
return nil,"Invalid IP Address"end
local n=y.parseDHCPData(o)if t<n.ipMin or t>n.ipEnd then
return nil,"Invalid start address"end
local i=t-n.network
local i,l=_(n.network,n.name,i,n.ipEnd-t+1,n.ipMax)if i then
a.sectionname=o
a.option="start"e.set_on_uci(a,t-n.network,r)a.option="limit"e.set_on_uci(a,n.ipEnd-t+1,r)return true
end
return i,l
end
function n.setDHCPMaxAddress(o,n,i)local t=f(n)if not t then
return nil,"Invalid IP Address"end
local n=y.parseDHCPData(o)if t<n.ipStart or t>n.ipMax then
return nil,"Invalid End address"end
local t=t-n.ipStart+1
local n,r=_(n.network,o,n.ipStart-n.network,t,n.ipMax)if n then
a.sectionname=o
a.option="limit"e.set_on_uci(a,t,i)return true
end
return n,r
end
function n.wlanRemotePort()local n
e.foreach_on_uci(D,function(e)if e.wlan_remote=="1"then
n=e.port
return false
end
end)return n
end
function n.getDHCPLanInterfaces()local t={}local r=n.getLanInterfaces()a.sectionname="dhcp"e.foreach_on_uci(a,function(n)for e in o(r)do
if n.interface==e then
t[#t+1]=n[".name"]break
end
end
end)return t
end
function n.getHostDataByName(n)return d("hostmanager.device","get",n)end
function n.convertEpochToISO(n)return n and os.date("!%Y-%m-%dT%H:%M:%SZ",n)or"9999-12-31T23:59:59Z"end
function n.getAccessPointInfo(n)return d("wireless.accesspoint","get",n)end
function n.getAccessPointStationInfo(n)return d("wireless.accesspoint.station","get",n)end
function n.getRadioInfo(n)return d("wireless.radio","get",n)end
function n.getSSIDStats(n)return d("wireless.ssid.stats","get",n)end
function n.stringToHex(n)return n and(n:gsub('.',function(n)return t.format('%02x',t.byte(n))end))end
function n.getMappingType(n)local n=n.objectType and n.objectType.name or""if n:match("^InternetGatewayDevice")then
return"igd"elseif n:match("^Device")then
return"device2"end
end
function n.getAPForIface(a)local t=""b.sectionname="wifi-ap"e.foreach_on_uci(b,function(n)if n.iface==a then
t=n[".name"]return false
end
end)return t
end
function n.getFirstLine(n)local e=""local n=k(n)if n then
e=n:read("*l")or""n:close()end
return e
end
function n.executeCommand(n)local e=""local n=m.popen(n)if n then
e=n:read("*l")or""n:close()end
return e
end
function n.getRebootReasons()local n={}local e=m.open("/lib/functions/reboot_reason.sh")if e then
for t in e:lines()do
if t:match("#.*REASONS_END")then
break
end
local e=t:match('(%w+)=%d+')if e then
if not e:match("RES")then
n[#n+1]=e
end
end
end
e:close()else
n={"GUI","CWMP","STS","CLI"}end
return n
end
function n.getExternalWifiIntfType()local n
if not c and not p then
local n=i:call("wireless.radio","get",{})if n then
for e,n in o(n)do
if n.remotely_managed==1 and n.integrated_ap==1 then
c=e
p=true
end
end
end
end
if c then
n=i:call("wireless.ssid","get",{})if not n then
return l,r
end
local e,a
local d=i:call("wireless.radio.remote","get",{name=c})if d then
local t,n=next(d)if n then
e=n.macaddr
a=n.ifname
end
end
for o,n in o(n)do
if n.radio==c then
local e=("0x"..t.sub(n.mac_address,(#n.mac_address-1)))local e=t.format("%02x",((e-1)%256))local n=t.sub(n.mac_address,1,(#n.mac_address-2))r=t.format("%s%s",n,e)if g==r then
break
end
end
if((r=="ff:ff:ff:ff:ff:ff")and c)then
if not l or not r then
r=e
l=a
end
end
end
if not l then
local n=i:call("hostmanager.device","get",{})or{}for e,n in o(n)do
if n["mac-address"]==r then
l=n.l2interface
end
end
end
if not l and r==e then
l=a
end
else
r=g
end
return l,r
end
function n.domainValidation(n)local e,t=0,0
if I(n)~="string"or#n==0 or#n>255 then
return nil,"Domain name cannot be empty or greater than 255 characters or non string value"end
repeat
e=e+1
t=S(n,".",e,true)local n=P(n,e,t)local n=s(n,"[^%.]*")if n~=nil then
if#n==0 or#n>63 then
return nil,"Label should not be empty or more than 63 characters"end
local e=s(n,"^[a-zA-z0-9][a-zA-Z0-9-_]*[a-zA-Z0-9]")if#n==1 then
if not s(n,"[a-zA-Z0-9]")then
return nil,"Label within domain name has invalid syntax"end
elseif n~=e then
return nil,"Label within domain name has invalid syntax"end
end
e=t
until not t
return true
end
function n.getNewSection(r,o)local n
local a={}u.config=r
u.sectionname=o
e.foreach_on_uci(u,function(n)a[n[".name"]]=true
end)repeat
n=e.generate_key()n=o.."_"..t.sub(n,-4)until not a[n]return n
end
return n