local o={}local e,f=io,string
local d=e.open
local e=require("modgui")local T=e.getRightLoggerModule()local n=require("transformer.mapper.ucihelper")local i="traceroute"local _,v=f.match,f.sub
local g,D,a,b=pairs,ipairs,tonumber,tostring
local t,h=os.remove,error
local S=require("transformer.mapper.nwcommon")local w=require("ubus").connect()local r={}local u={}local l={}local m={}local p={}local e={}local function s(e,o,t)n.set_on_uci(e,o,t)r[e.config]=true
end
function o.clear_traceroute_results(e)t("/tmp/traceroute_"..e)t("/tmp/trace_"..e)l[e]=nil
m[e]=0
p[e]=""end
function o.parseLine(e)local o,t,n
for c in e:gmatch("[^*]*%*")do
local i,r,e=_(c,"%S+%s+(%S+)%s+%((%S+)%)%s+(%d+%.%d+)%s+ms")if(i)then
o=i
t=r
else
e=_(c,"(%d+%.%d+)%s+ms")end
e=e or"0"if(n)then
n=n..","..e
else
n=e
end
end
return o,t,n
end
function o.read_trace_results(e,n)local c={}local r,n=d(n,"r")if not r then
T:debug("traceroute results not found: "..n)return c,0
end
local u=a(r:read())local s
if e~="diagping"and e~="webui"then
s=r:read()end
for a in r:lines()do
local r="0"local t,i,n
a=f.gsub(a,"(%S%sms)","%1*")if e=="diagping"or e=="webui"then
if a:match("(%d+%s+)%*")then
t,i,n="*","*","*"r="*"else
t,i,n=o.parseLine(a)end
else
t,i,n=_(a,"(%S+)%s+(%S+)%s+(%S+)")end
if(t and i)then
if n~="*"then
n=n and v(n,1,20)end
if(t==i)and t~="*"then
t=""end
c[#c+1]={t,i,n,r}end
end
r:close()if e~="diagping"and e~="webui"then
l[e],m[e],p[e]=c,u,s
end
return c,u,s
end
function o.read_traceroute_results(e,n)if e=="diagping"or e=="webui"then
return o.read_trace_results(e,"/tmp/trace_"..e)elseif(l[e])then
return l[e],m[e]end
return o.read_trace_results(e,"/tmp/traceroute_"..e)end
function o.startup(t,o)e[t]=o
local o=d("/etc/config/traceroute")if not o then
o=d("/etc/config/traceroute","w")if not o then
h("could not create /etc/config/traceroute")end
o:write("config  user '"..t.."'\n")o:close()n.set_on_uci(e[t]["NumberOfTries"],3)n.set_on_uci(e[t]["Timeout"],5000)n.set_on_uci(e[t]["DataBlockSize"],38)n.set_on_uci(e[t]["DSCP"],0)n.set_on_uci(e[t]["MaxHopCount"],30)n.set_on_uci(e[t]["ProtocolVersion"],"IPv4")if t=="webui"then
n.set_on_uci(e[t]["Timeout"],3000)end
else
local o=n.get_from_uci({config="traceroute",sectionname=t})if o==''then
n.set_on_uci({config="traceroute",sectionname=t},"user")n.set_on_uci(e[t]["NumberOfTries"],3)n.set_on_uci(e[t]["Timeout"],5000)n.set_on_uci(e[t]["DataBlockSize"],38)n.set_on_uci(e[t]["DSCP"],0)n.set_on_uci(e[t]["MaxHopCount"],30)n.set_on_uci(e[t]["ProtocolVersion"],"IPv4")if t=="webui"then
n.set_on_uci(e[t]["Timeout"],3000)end
end
end
n.set_on_uci(e[t]["DiagnosticsState"],"None")n.commit({config="traceroute"})return t
end
function o.uci_traceroute_get(t,r)local c
if e[t]==nil then
e[t]={DiagnosticsState={config=i,sectionname=t,option="state"},Interface={config=i,sectionname=t,option="interface"},Host={config=i,sectionname=t,option="host"},NumberOfTries={config=i,sectionname=t,option="tries"},Timeout={config=i,sectionname=t,option="timeout"},DataBlockSize={config=i,sectionname=t,option="size"},DSCP={config=i,sectionname=t,option="dscp"},MaxHopCount={config=i,sectionname=t,option="hopcount"},ProtocolVersion={config=i,sectionname=t,option="type"},}end
if e[t][r]then
c=n.get_from_uci(e[t][r])if r=="DiagnosticsState"and c=="InProgress"then
c="Requested"end
elseif(r=="ResponseTime")then
local n,e=o.read_traceroute_results(t)c=(e and b(e))or"0"else
return nil,"invalid parameter"end
return c
end
function o.uci_traceroute_set(t,r,i,c)if r=="DiagnosticsState"then
if i~="Requested"and i~="Canceled"then
return nil,"invalid value"elseif i=="Requested"and t=="device2"then
local t=o.uci_traceroute_get(t,"Interface")if t==""then
local n=S.loadRoutes(true)if n then
local e=w:call("network.interface","dump",{})for o,e in D(e.interface or{})do
if e.l3_device==n then
t=e.interface
break
end
end
end
end
end
u[t]=true
if i=="Canceled"then
s(e[t]["DiagnosticsState"],"None",c)else
s(e[t]["DiagnosticsState"],i,c)end
elseif(r=="ResponseTime")then
return nil,"invalid parameter"else
local n=n.get_from_uci(e[t]["DiagnosticsState"])if(n~="Requested")and(n~="None")then
s(e[t]["DiagnosticsState"],"None",c)end
s(e[t][r],i,c)end
end
function o.uci_traceroute_commit()for e,n in g(u)do
o.clear_traceroute_results(e)end
u={}for e in g(r)do
local e={config=e}n.commit(e)end
r={}end
function o.uci_traceroute_revert()u={}for e in g(r)do
local e={config=e}n.revert(e)end
r={}end
return o