mirror of
				https://github.com/Ysurac/openmptcprouter-feeds.git
				synced 2025-03-09 15:40:03 +00:00 
			
		
		
		
	
		
			
				
	
	
		
			1449 lines
		
	
	
		
			No EOL
		
	
	
		
			48 KiB
		
	
	
	
		
			Lua
		
	
	
		
			Executable file
		
	
	
	
	
			
		
		
	
	
			1449 lines
		
	
	
		
			No EOL
		
	
	
		
			48 KiB
		
	
	
	
		
			Lua
		
	
	
		
			Executable file
		
	
	
	
	
#!/usr/bin/env lua
 | 
						|
 | 
						|
local math  = require "math"
 | 
						|
local sys   = require "luci.sys"
 | 
						|
local json  = require("luci.json")
 | 
						|
local fs    = require("nixio.fs")
 | 
						|
local net   = require "luci.model.network".init()
 | 
						|
local ucic  = require "luci.model.uci".cursor()
 | 
						|
local jsonc  = require "luci.jsonc"
 | 
						|
 | 
						|
function interface_from_device(dev)
 | 
						|
	for _, iface in ipairs(net:get_networks()) do
 | 
						|
		local ifacen = iface:name()
 | 
						|
		local ifacename = ucic:get("network",ifacen,"ifname")
 | 
						|
		if ifacename == dev then
 | 
						|
			return ifacen
 | 
						|
		end
 | 
						|
	end
 | 
						|
	return ""
 | 
						|
end
 | 
						|
 | 
						|
function add_server(add_server_name)
 | 
						|
	ucic:set("openmptcprouter",add_server_name:gsub("[^%w_]+","_"),"server")
 | 
						|
	ucic:save("openmptcprouter")
 | 
						|
	ucic:commit("openmptcprouter")
 | 
						|
end
 | 
						|
 | 
						|
function remove_server(serverdel)
 | 
						|
	-- Remove existing server
 | 
						|
	ucic:foreach("network", "interface", function(s)
 | 
						|
		local sectionname = s[".name"]
 | 
						|
		ucic:delete("network","server_" .. serverdel .. "_" .. sectionname .. "_route")
 | 
						|
	end)
 | 
						|
	ucic:delete("network","server_" .. serverdel .. "_default_route")
 | 
						|
	ucic:delete("openmptcprouter",serverdel)
 | 
						|
	ucic:save("openmptcprouter")
 | 
						|
	ucic:commit("openmptcprouter")
 | 
						|
	ucic:save("network")
 | 
						|
	ucic:commit("network")
 | 
						|
end
 | 
						|
 | 
						|
function add_interface(add_interface_ifname)
 | 
						|
	-- Add new interface
 | 
						|
	local i = 1
 | 
						|
	local multipath_master = false
 | 
						|
	ucic:foreach("network", "interface", function(s)
 | 
						|
		local sectionname = s[".name"]
 | 
						|
		if sectionname:match("^wan(%d+)$") then
 | 
						|
			i = i + 1
 | 
						|
		end
 | 
						|
		if ucic:get("network",sectionname,"multipath") == "master" then
 | 
						|
			multipath_master = true
 | 
						|
		end
 | 
						|
	end)
 | 
						|
	local defif = "eth0"
 | 
						|
	if add_interface_ifname == "" then
 | 
						|
		local defif1 = ucic:get("network","wan1_dev","ifname") or ""
 | 
						|
		if defif1 ~= "" then
 | 
						|
			defif = defif1
 | 
						|
		end
 | 
						|
	else
 | 
						|
		defif = add_interface_ifname
 | 
						|
	end
 | 
						|
 | 
						|
	local ointf = interface_from_device(defif) or ""
 | 
						|
	local wanif = defif
 | 
						|
	if ointf ~= "" then
 | 
						|
		if ucic:get("network",ointf,"type") == "" then
 | 
						|
			ucic:set("network",ointf,"type","macvlan")
 | 
						|
		end
 | 
						|
		wanif = "wan" .. i
 | 
						|
	end
 | 
						|
 | 
						|
	ucic:set("network","wan" .. i,"interface")
 | 
						|
	ucic:set("network","wan" .. i,"ifname",defif)
 | 
						|
	ucic:set("network","wan" .. i,"proto","static")
 | 
						|
	if ointf ~= "" then
 | 
						|
		ucic:set("network","wan" .. i,"type","macvlan")
 | 
						|
	end
 | 
						|
	ucic:set("network","wan" .. i,"ip4table","wan")
 | 
						|
	if multipath_master then
 | 
						|
		ucic:set("network","wan" .. i,"multipath","on")
 | 
						|
		ucic:set("openmptcprouter","wan" .. i,"multipath","on")
 | 
						|
	else
 | 
						|
		ucic:set("network","wan" .. i,"multipath","master")
 | 
						|
		ucic:set("openmptcprouter","wan" .. i,"multipath","master")
 | 
						|
	end
 | 
						|
	ucic:set("network","wan" .. i,"defaultroute","0")
 | 
						|
	ucic:reorder("network","wan" .. i, i + 2)
 | 
						|
	ucic:save("network")
 | 
						|
	ucic:commit("network")
 | 
						|
 | 
						|
	ucic:set("qos","wan" .. i,"interface")
 | 
						|
	ucic:set("qos","wan" .. i,"classgroup","Default")
 | 
						|
	ucic:set("qos","wan" .. i,"enabled","0")
 | 
						|
	ucic:set("qos","wan" .. i,"upload","4000")
 | 
						|
	ucic:set("qos","wan" .. i,"download","100000")
 | 
						|
	ucic:save("qos")
 | 
						|
	ucic:commit("qos")
 | 
						|
 | 
						|
	ucic:set("sqm","wan" .. i,"queue")
 | 
						|
	if ointf ~= "" then
 | 
						|
		ucic:set("sqm","wan" .. i,"interface","wan" .. i)
 | 
						|
	else
 | 
						|
		ucic:set("sqm","wan" .. i,"interface",defif)
 | 
						|
	end
 | 
						|
	ucic:set("sqm","wan" .. i,"qdisc","fq_codel")
 | 
						|
	ucic:set("sqm","wan" .. i,"script","simple.qos")
 | 
						|
	ucic:set("sqm","wan" .. i,"qdisc_advanced","0")
 | 
						|
	ucic:set("sqm","wan" .. i,"linklayer","none")
 | 
						|
	ucic:set("sqm","wan" .. i,"enabled","0")
 | 
						|
	ucic:set("sqm","wan" .. i,"debug_logging","0")
 | 
						|
	ucic:set("sqm","wan" .. i,"verbosity","5")
 | 
						|
	ucic:set("sqm","wan" .. i,"download","0")
 | 
						|
	ucic:set("sqm","wan" .. i,"upload","0")
 | 
						|
	ucic:save("sqm")
 | 
						|
	ucic:commit("sqm")
 | 
						|
 | 
						|
	luci.sys.call("uci -q add_list vnstat.@vnstat[-1].interface=" .. wanif)
 | 
						|
	luci.sys.call("uci -q commit vnstat")
 | 
						|
 | 
						|
	-- Dirty way to add new interface to firewall...
 | 
						|
	luci.sys.call("uci -q add_list firewall.@zone[1].network=wan" .. i)
 | 
						|
	luci.sys.call("uci -q commit firewall")
 | 
						|
 | 
						|
	luci.sys.call("/etc/init.d/macvlan restart >/dev/null 2>/dev/null")
 | 
						|
end
 | 
						|
 | 
						|
function remove_interface(intf)
 | 
						|
	-- Remove existing interface
 | 
						|
	local defif = ucic:get("network",intf,"ifname")
 | 
						|
	ucic:delete("network",intf)
 | 
						|
	ucic:delete("network",intf .. "_dev")
 | 
						|
	ucic:save("network")
 | 
						|
	ucic:commit("network")
 | 
						|
	ucic:delete("sqm",intf)
 | 
						|
	ucic:save("sqm")
 | 
						|
	ucic:commit("sqm")
 | 
						|
	ucic:delete("qos",intf)
 | 
						|
	ucic:save("qos")
 | 
						|
	ucic:commit("qos")
 | 
						|
	if defif ~= nil and defif ~= "" then
 | 
						|
		luci.sys.call("uci -q del_list vnstat.@vnstat[-1].interface=" .. defif)
 | 
						|
	end
 | 
						|
	luci.sys.call("uci -q commit vnstat")
 | 
						|
	luci.sys.call("uci -q del_list firewall.@zone[1].network=" .. intf)
 | 
						|
	luci.sys.call("uci -q commit firewall")
 | 
						|
end
 | 
						|
 | 
						|
function set_interface(intf,proto,ipaddr,netmask,gateway,sqmenabled,downloadspeed,uploadspeed)
 | 
						|
	-- Set interfaces settings
 | 
						|
	if proto ~= "other" then
 | 
						|
		ucic:set("network",intf,"proto",proto)
 | 
						|
	end
 | 
						|
	ucic:set("network",intf,"ipaddr",ipaddr)
 | 
						|
	ucic:set("network",intf,"netmask",netmask)
 | 
						|
	ucic:set("network",intf,"gateway",gateway)
 | 
						|
 | 
						|
	ucic:delete("openmptcprouter",intf,"lc")
 | 
						|
	ucic:save("openmptcprouter")
 | 
						|
 | 
						|
	if not ucic:get("qos",intf) ~= "" then
 | 
						|
		ucic:set("qos",intf,"interface")
 | 
						|
		ucic:set("qos",intf,"classgroup","Default")
 | 
						|
		ucic:set("qos",intf,"enabled","0")
 | 
						|
		ucic:set("qos",intf,"upload","4000")
 | 
						|
		ucic:set("qos",intf,"download","100000")
 | 
						|
	end
 | 
						|
 | 
						|
	if not ucic:get("sqm",intf) ~= "" then
 | 
						|
		local defif = get_device(intf)
 | 
						|
		if defif == "" then
 | 
						|
			defif = ucic:get("network",intf,"ifname") or ""
 | 
						|
		end
 | 
						|
		ucic:set("sqm",intf,"queue")
 | 
						|
		ucic:set("sqm",intf,"interface",defif)
 | 
						|
		ucic:set("sqm",intf,"qdisc","fq_codel")
 | 
						|
		ucic:set("sqm",intf,"script","simple.qos")
 | 
						|
		ucic:set("sqm",intf,"qdisc_advanced","0")
 | 
						|
		ucic:set("sqm",intf,"linklayer","none")
 | 
						|
		ucic:set("sqm",intf,"enabled","0")
 | 
						|
		ucic:set("sqm",intf,"debug_logging","0")
 | 
						|
		ucic:set("sqm",intf,"verbosity","5")
 | 
						|
		ucic:set("sqm",intf,"download","0")
 | 
						|
		ucic:set("sqm",intf,"upload","0")
 | 
						|
	end
 | 
						|
 | 
						|
	if downloadspeed ~= "0" and uploadspeed ~= "0" then
 | 
						|
		ucic:set("network",intf,"downloadspeed",downloadspeed)
 | 
						|
		ucic:set("network",intf,"uploadspeed",uploadspeed)
 | 
						|
		ucic:set("sqm",intf,"download",math.ceil(downloadspeed*95/100))
 | 
						|
		ucic:set("sqm",intf,"upload",math.ceil(uploadspeed*95/100))
 | 
						|
		if sqmenabled == "1" then
 | 
						|
			ucic:set("sqm",intf,"enabled","1")
 | 
						|
		else
 | 
						|
			ucic:set("sqm",intf,"enabled","0")
 | 
						|
		end
 | 
						|
		ucic:set("qos",intf,"download",math.ceil(downloadspeed*95/100))
 | 
						|
		ucic:set("qos",intf,"upload",math.ceil(uploadspeed*95/100))
 | 
						|
		if sqmenabled == "1" then
 | 
						|
			ucic:set("qos",intf,"enabled","1")
 | 
						|
		else
 | 
						|
			ucic:set("qos",intf,"enabled","0")
 | 
						|
		end
 | 
						|
	else
 | 
						|
		ucic:set("sqm",intf,"download","0")
 | 
						|
		ucic:set("sqm",intf,"upload","0")
 | 
						|
		ucic:set("sqm",intf,"enabled","0")
 | 
						|
		ucic:set("qos",intf,"download","0")
 | 
						|
		ucic:set("qos",intf,"upload","0")
 | 
						|
		ucic:set("qos",intf,"enabled","0")
 | 
						|
	end
 | 
						|
 | 
						|
	-- Disable multipath on LAN, VPN and loopback
 | 
						|
	ucic:set("network","loopback","multipath","off")
 | 
						|
	ucic:set("network","lan","multipath","off")
 | 
						|
	ucic:set("network","omr6in4","multipath","off")
 | 
						|
	ucic:set("network","omrvpn","multipath","off")
 | 
						|
 | 
						|
	ucic:save("sqm")
 | 
						|
	ucic:commit("sqm")
 | 
						|
	ucic:save("qos")
 | 
						|
	ucic:commit("qos")
 | 
						|
	ucic:save("network")
 | 
						|
	ucic:commit("network")
 | 
						|
	ucic:save("openmptcprouter")
 | 
						|
	ucic:commit("openmptcprouter")
 | 
						|
end
 | 
						|
 | 
						|
function default_vpn(default_vpn)
 | 
						|
	-- Get VPN set by default
 | 
						|
	local vpn_port = ""
 | 
						|
	local vpn_intf = ""
 | 
						|
	if default_vpn:match("^glorytun.*") then
 | 
						|
		vpn_port = 65001
 | 
						|
		vpn_intf = "tun0"
 | 
						|
		--ucic:set("network","omrvpn","proto","dhcp")
 | 
						|
		ucic:set("network","omrvpn","proto","none")
 | 
						|
		if default_vpn == "glorytun_udp" then
 | 
						|
			ucic:set("glorytun","vpn","proto","udp")
 | 
						|
			ucic:set("glorytun","vpn","localip","10.255.254.2")
 | 
						|
			ucic:set("glorytun","vpn","remoteip","10.255.254.1")
 | 
						|
			ucic:set("network","omr6in4","ipaddr","10.255.254.2")
 | 
						|
			ucic:set("network","omr6in4","peeraddr","10.255.254.1")
 | 
						|
		else
 | 
						|
			ucic:set("glorytun","vpn","proto","tcp")
 | 
						|
			ucic:set("glorytun","vpn","localip","10.255.255.2")
 | 
						|
			ucic:set("glorytun","vpn","remoteip","10.255.255.1")
 | 
						|
			ucic:set("network","omr6in4","ipaddr","10.255.255.2")
 | 
						|
			ucic:set("network","omr6in4","peeraddr","10.255.255.1")
 | 
						|
		end
 | 
						|
	elseif default_vpn == "dsvpn" then
 | 
						|
		vpn_port = 65011
 | 
						|
		vpn_intf = "tun0"
 | 
						|
		--ucic:set("network","omrvpn","proto","dhcp")
 | 
						|
		ucic:set("network","omrvpn","proto","none")
 | 
						|
		ucic:set("dsvpn","vpn","localip","10.255.251.2")
 | 
						|
		ucic:set("dsvpn","vpn","remoteip","10.255.251.1")
 | 
						|
		ucic:set("network","omr6in4","ipaddr","10.255.251.2")
 | 
						|
		ucic:set("network","omr6in4","peeraddr","10.255.251.1")
 | 
						|
	elseif default_vpn == "mlvpn" then
 | 
						|
		vpn_port = 65201
 | 
						|
		vpn_intf = "mlvpn0"
 | 
						|
		ucic:set("network","omrvpn","proto","dhcp")
 | 
						|
	elseif default_vpn == "openvpn" then
 | 
						|
		vpn_port = 65301
 | 
						|
		vpn_intf = "tun0"
 | 
						|
		ucic:set("network","omrvpn","proto","dhcp")
 | 
						|
	end
 | 
						|
	if vpn_intf ~= "" then
 | 
						|
		ucic:set("network","omrvpn","ifname",vpn_intf)
 | 
						|
		ucic:save("network")
 | 
						|
		ucic:commit("network")
 | 
						|
	end
 | 
						|
	-- Set Glorytun settings
 | 
						|
	if default_vpn:match("^glorytun.*") then
 | 
						|
		ucic:set("glorytun","vpn","enable",1)
 | 
						|
	else
 | 
						|
		ucic:set("glorytun","vpn","enable",0)
 | 
						|
	end
 | 
						|
	-- Set A Dead Simple VPN settings
 | 
						|
	if default_vpn == "dsvpn" then
 | 
						|
		ucic:set("dsvpn","vpn","enable",1)
 | 
						|
	else
 | 
						|
		ucic:set("dsvpn","vpn","enable",0)
 | 
						|
	end
 | 
						|
	-- Set MLVPN settings
 | 
						|
	if default_vpn == "mlvpn" then
 | 
						|
		ucic:set("mlvpn","general","enable",1)
 | 
						|
		ucic:set("network","omrvpn","proto","dhcp")
 | 
						|
	else
 | 
						|
		ucic:set("mlvpn","general","enable",0)
 | 
						|
	end
 | 
						|
	if default_vpn == "openvpn" then
 | 
						|
		ucic:set("openvpn","omr","enabled",1)
 | 
						|
		ucic:set("network","omrvpn","proto","dhcp")
 | 
						|
	else
 | 
						|
		ucic:set("openvpn","omr","enabled",0)
 | 
						|
	end
 | 
						|
	ucic:set("openmptcprouter","settings","vpn",default_vpn)
 | 
						|
	ucic:save("glorytun")
 | 
						|
	ucic:commit("glorytun")
 | 
						|
	ucic:save("mlvpn")
 | 
						|
	ucic:commit("mlvpn")
 | 
						|
	ucic:save("dsvpn")
 | 
						|
	ucic:commit("dsvpn")
 | 
						|
	ucic:save("openvpn")
 | 
						|
	ucic:commit("openvpn")
 | 
						|
	ucic:save("openmptcprouter")
 | 
						|
	ucic:commit("openmptcprouter")
 | 
						|
	ucic:save("network")
 | 
						|
	ucic:commit("network")
 | 
						|
 | 
						|
end
 | 
						|
 | 
						|
function server_settings(server,server_ip,openmptcprouter_vps_key)
 | 
						|
	-- OpenMPTCProuter VPS
 | 
						|
	ucic:set("openmptcprouter",server,"server")
 | 
						|
	ucic:set("openmptcprouter",server,"username","openmptcprouter")
 | 
						|
	ucic:set("openmptcprouter",server,"password",openmptcprouter_vps_key)
 | 
						|
	ucic:set("openmptcprouter",server,"ip",server_ip)
 | 
						|
	ucic:set("openmptcprouter",server,"port","65500")
 | 
						|
	ucic:save("openmptcprouter")
 | 
						|
	ucic:set("shadowsocks-libev","sss0","server",server_ip)
 | 
						|
	ucic:set("glorytun","vpn","host",server_ip)
 | 
						|
	ucic:set("dsvpn","vpn","host",server_ip)
 | 
						|
	ucic:set("mlvpn","general","host",server_ip)
 | 
						|
	luci.sys.call("uci -q del openvpn.omr.remote")
 | 
						|
	luci.sys.call("uci -q add_list openvpn.omr.remote=" .. server_ip)
 | 
						|
	ucic:set("qos","serverin","srchost",server_ip)
 | 
						|
	ucic:set("qos","serverout","dsthost",server_ip)
 | 
						|
	ucic:save("qos")
 | 
						|
	ucic:commit("qos")
 | 
						|
	ucic:save("mlvpn")
 | 
						|
	ucic:commit("mlvpn")
 | 
						|
	ucic:save("dsvpn")
 | 
						|
	ucic:commit("dsvpn")
 | 
						|
	ucic:save("glorytun")
 | 
						|
	ucic:commit("glorytun")
 | 
						|
	ucic:save("shadowsocks-libev")
 | 
						|
	ucic:commit("shadowsocks-libev")
 | 
						|
end
 | 
						|
 | 
						|
function set_shadowsocks(shadowsocks_key)
 | 
						|
	-- Set ShadowSocks settings
 | 
						|
	ucic:set("shadowsocks-libev","sss0","key",shadowsocks_key)
 | 
						|
	ucic:save("shadowsocks-libev")
 | 
						|
	ucic:commit("shadowsocks-libev")
 | 
						|
end
 | 
						|
 | 
						|
function disable_shadowsocks(shadowsocks_disable)
 | 
						|
	-- Set ShadowSocks settings
 | 
						|
	ucic:set("shadowsocks-libev","sss0","disabled",shadowsocks_disable)
 | 
						|
	ucic:save("shadowsocks-libev")
 | 
						|
	ucic:commit("shadowsocks-libev")
 | 
						|
end
 | 
						|
 | 
						|
function set_glorytun(glorytun_key)
 | 
						|
	ucic:set("glorytun","vpn","port","65001")
 | 
						|
	ucic:set("glorytun","vpn","key",glorytun_key)
 | 
						|
	ucic:set("glorytun","vpn","mptcp",1)
 | 
						|
	ucic:set("glorytun","vpn","chacha20",1)
 | 
						|
	ucic:save("glorytun")
 | 
						|
	ucic:commit("glorytun")
 | 
						|
end
 | 
						|
 | 
						|
function set_dsvpn(dsvpn_key)
 | 
						|
	ucic:set("dsvpn","vpn","port","65011")
 | 
						|
	ucic:set("dsvpn","vpn","key",dsvpn_key)
 | 
						|
	ucic:save("glorytun")
 | 
						|
	ucic:commit("glorytun")
 | 
						|
end
 | 
						|
 | 
						|
function set_mlvpn(mlvpn_password)
 | 
						|
	-- Set MLVPN settings
 | 
						|
	local mlvpn_password = luci.http.formvalue("mlvpn_password")
 | 
						|
	ucic:set("mlvpn","general","password",mlvpn_password)
 | 
						|
	ucic:set("mlvpn","general","firstport","65201")
 | 
						|
	ucic:set("mlvpn","general","interface_name","mlvpn0")
 | 
						|
	ucic:save("mlvpn")
 | 
						|
	ucic:commit("mlvpn")
 | 
						|
end
 | 
						|
 | 
						|
function set_openvpn(openvpn_key)
 | 
						|
	-- Set OpenVPN settings
 | 
						|
	local openvpn_key_path = "/etc/luci-uploads/openvpn.key"
 | 
						|
	local fp
 | 
						|
	luci.http.setfilehandler(
 | 
						|
		function(meta, chunk, eof)
 | 
						|
			if not fp and meta and meta.name == "openvpn_key" then
 | 
						|
				fp = io.open(openvpn_key_path, "w")
 | 
						|
			end
 | 
						|
			if fp and chunk then
 | 
						|
				fp:write(chunk)
 | 
						|
			end
 | 
						|
			if fp and eof then
 | 
						|
				fp:close()
 | 
						|
			end
 | 
						|
		end)
 | 
						|
	ucic:set("openvpn","omr","secret",openvpn_key_path)
 | 
						|
	ucic:save("openvpn")
 | 
						|
	ucic:commit("openvpn")
 | 
						|
end
 | 
						|
 | 
						|
function restart_all()
 | 
						|
	-- Restart all
 | 
						|
	luci.sys.call("(env -i /bin/ubus call network reload) >/dev/null 2>/dev/null")
 | 
						|
	luci.sys.call("/etc/init.d/mptcp restart >/dev/null 2>/dev/null")
 | 
						|
	luci.sys.call("/etc/init.d/openmptcprouter-vps restart >/dev/null 2>/dev/null")
 | 
						|
	os.execute("sleep 2")
 | 
						|
	luci.sys.call("/etc/init.d/shadowsocks-libev restart >/dev/null 2>/dev/null")
 | 
						|
	luci.sys.call("/etc/init.d/glorytun restart >/dev/null 2>/dev/null")
 | 
						|
	luci.sys.call("/etc/init.d/glorytun-udp restart >/dev/null 2>/dev/null")
 | 
						|
	--luci.sys.call("/etc/init.d/mlvpn restart >/dev/null 2>/dev/null")
 | 
						|
	luci.sys.call("/etc/init.d/openvpn restart >/dev/null 2>/dev/null")
 | 
						|
	luci.sys.call("/etc/init.d/omr-tracker restart >/dev/null 2>/dev/null")
 | 
						|
	luci.sys.call("/etc/init.d/omr-6in4 restart >/dev/null 2>/dev/null")
 | 
						|
end
 | 
						|
 | 
						|
function redirectports(server,redirect_ports)
 | 
						|
	ucic:set("openmptcprouter",server,"redirect_ports",value)
 | 
						|
	ucic:commit("openmptcprouter")
 | 
						|
end
 | 
						|
 | 
						|
function tcpkeepalivetime(tcp_keepalive_time)
 | 
						|
	-- Set tcp_keepalive_time
 | 
						|
	luci.sys.exec("sysctl -w net.ipv4.tcp_keepalive_time=%s" % tcp_keepalive_time)
 | 
						|
	luci.sys.exec("sed -i 's:^net.ipv4.tcp_keepalive_time=[0-9]*:net.ipv4.tcp_keepalive_time=%s:' /etc/sysctl.d/zzz_openmptcprouter.conf" % tcp_keepalive_time)
 | 
						|
end
 | 
						|
 | 
						|
function tcpfintimeout(tcp_fin_timeout)
 | 
						|
	-- Set tcp_fin_timeout
 | 
						|
	luci.sys.exec("sysctl -w net.ipv4.tcp_fin_timeout=%s" % tcp_fin_timeout)
 | 
						|
	luci.sys.exec("sed -i 's:^net.ipv4.tcp_fin_timeout=[0-9]*:net.ipv4.tcp_fin_timeout=%s:' /etc/sysctl.d/zzz_openmptcprouter.conf" % tcp_fin_timeout)
 | 
						|
end
 | 
						|
 | 
						|
function tcpsynretries(tcp_syn_retries)
 | 
						|
	-- Set tcp_syn_retries
 | 
						|
	luci.sys.exec("sysctl -w net.ipv4.tcp_syn_retries=%s" % tcp_syn_retries)
 | 
						|
	luci.sys.exec("sed -i 's:^net.ipv4.tcp_syn_retries=[0-9]*:net.ipv4.tcp_syn_retries=%s:' /etc/sysctl.d/zzz_openmptcprouter.conf" % tcp_syn_retries)
 | 
						|
end
 | 
						|
 | 
						|
function tcpfastopen(tcp_fastopen)
 | 
						|
	-- Set tcp_fastopen
 | 
						|
	luci.sys.exec("sysctl -w net.ipv4.tcp_fastopen=%s" % tcp_fastopen)
 | 
						|
	luci.sys.exec("sed -i 's:^net.ipv4.tcp_fastopen=[0-3]*:net.ipv4.tcp_fastopen=%s:' /etc/sysctl.d/zzz_openmptcprouter.conf" % tcp_fastopen)
 | 
						|
end
 | 
						|
 | 
						|
function disableipv6(disable_ipv6)
 | 
						|
	-- Disable IPv6
 | 
						|
	ucic:set("openmptcprouter","settings","disable_ipv6",disable_ipv6)
 | 
						|
	ucic:save("openmptcprouter")
 | 
						|
	ucic:commit("openmptcprouter")
 | 
						|
	luci.sys.call("/etc/init.d/omr-6in4 restart >/dev/null 2>/dev/null")
 | 
						|
end
 | 
						|
 | 
						|
function externalcheck(externalcheck)
 | 
						|
	-- Enable/disable external check
 | 
						|
	ucic:set("openmptcprouter","settings","external_check",externalcheck)
 | 
						|
	ucic:commit("openmptcprouter")
 | 
						|
end
 | 
						|
 | 
						|
function savevnstat(savevnstat)
 | 
						|
	-- Enable/disable save vnstat
 | 
						|
	luci.sys.exec("uci -q set vnstat.@vnstat[0].backup=%s" % savevnstat)
 | 
						|
	ucic:commit("vnstat")
 | 
						|
end
 | 
						|
 | 
						|
function disablefastopen(disablefastopen)
 | 
						|
	-- Enable/disable fast open
 | 
						|
	if disablefastopen == "0" then
 | 
						|
		fastopen = "1"
 | 
						|
	else
 | 
						|
		fastopen = "0"
 | 
						|
	end
 | 
						|
	ucic:foreach("shadowsocks-libev", "ss_redir", function (section)
 | 
						|
		ucic:set("shadowsocks-libev",section[".name"],"fast_open",fastopen)
 | 
						|
	end)
 | 
						|
	ucic:foreach("shadowsocks-libev", "ss_local", function (section)
 | 
						|
		ucic:set("shadowsocks-libev",section[".name"],"fast_open",fastopen)
 | 
						|
	end)
 | 
						|
end
 | 
						|
 | 
						|
function enableobfs(obfs,obfs_plugin,obfs_type)
 | 
						|
	-- Enable/disable obfs
 | 
						|
	ucic:foreach("shadowsocks-libev", "server", function (section)
 | 
						|
		ucic:set("shadowsocks-libev",section[".name"],"obfs",obfs)
 | 
						|
		ucic:set("shadowsocks-libev",section[".name"],"obfs_plugin",obfs_plugin)
 | 
						|
		ucic:set("shadowsocks-libev",section[".name"],"obfs_type",obfs_type)
 | 
						|
	end)
 | 
						|
	ucic:save("shadowsocks-libev")
 | 
						|
	ucic:commit("shadowsocks-libev")
 | 
						|
end
 | 
						|
 | 
						|
function setmastertype(master_type)
 | 
						|
	-- Set master to dynamic or static
 | 
						|
	ucic:set("openmptcprouter","settings","master",master_type)
 | 
						|
	ucic:commit("openmptcprouter")
 | 
						|
end
 | 
						|
 | 
						|
function cpuscalingmin(scaling_min_freq)
 | 
						|
	-- Set CPU scaling minimum frequency
 | 
						|
	ucic:set("openmptcprouter","settings","scaling_min_freq",scaling_min_freq)
 | 
						|
	ucic:save("openmptcprouter")
 | 
						|
	ucic:commit("openmptcprouter")
 | 
						|
end
 | 
						|
 | 
						|
function cpuscalingmax(scaling_max_freq)
 | 
						|
	-- Set CPU scaling maximum frequency
 | 
						|
	ucic:set("openmptcprouter","settings","scaling_max_freq",scaling_max_freq)
 | 
						|
	ucic:save("openmptcprouter")
 | 
						|
	ucic:commit("openmptcprouter")
 | 
						|
end
 | 
						|
 | 
						|
function cpuscalinggovernor(scaling_governor)
 | 
						|
	-- Set CPU governor
 | 
						|
	ucic:set("openmptcprouter","settings","scaling_governor",scaling_governor)
 | 
						|
	ucic:save("openmptcprouter")
 | 
						|
	ucic:commit("openmptcprouter")
 | 
						|
end
 | 
						|
 | 
						|
function update_vps()
 | 
						|
	-- Update VPS
 | 
						|
	ucic:foreach("openmptcprouter", "server", function(s)
 | 
						|
		local serverip = ucic:get("openmptcprouter",s[".name"],"ip")
 | 
						|
		local adminport = ucic:get("openmptcprouter",s[".name"],"port") or "65500"
 | 
						|
		local token = ucic:get("openmptcprouter",s[".name"],"token") or ""
 | 
						|
		if token ~= "" then
 | 
						|
			sys.exec('curl -4 --max-time 20 -s -k -H "Authorization: Bearer ' .. token .. '" https://' .. serverip .. ":" .. adminport .. "/update")
 | 
						|
			luci.sys.call("/etc/init.d/openmptcprouter-vps restart >/dev/null 2>/dev/null")
 | 
						|
			luci.http.redirect(luci.dispatcher.build_url("admin/system/openmptcprouter/status"))
 | 
						|
			return
 | 
						|
		end
 | 
						|
	end)
 | 
						|
end
 | 
						|
 | 
						|
function get_ip(interface)
 | 
						|
	local dump = require("luci.util").ubus("network.interface.%s" % interface, "status", {})
 | 
						|
	local ip = ""
 | 
						|
	if dump and dump['ipv4-address'] then
 | 
						|
		local _, ipv4address
 | 
						|
		for _, ipv4address in ipairs(dump['ipv4-address']) do
 | 
						|
			ip = dump['ipv4-address'][_].address
 | 
						|
		end
 | 
						|
	end
 | 
						|
	if ip == "" then
 | 
						|
		local dump = require("luci.util").ubus("network.interface.%s_4" % interface, "status", {})
 | 
						|
		if dump and dump['ipv4-address'] then
 | 
						|
			local _, ipv4address
 | 
						|
			for _, ipv4address in ipairs(dump['ipv4-address']) do
 | 
						|
				ip = dump['ipv4-address'][_].address
 | 
						|
			end
 | 
						|
		end
 | 
						|
	end
 | 
						|
	return ip
 | 
						|
end
 | 
						|
 | 
						|
function get_device(interface)
 | 
						|
	local dump = require("luci.util").ubus("network.interface.%s" % interface, "status", {})
 | 
						|
	if dump then
 | 
						|
		return dump['l3_device']
 | 
						|
	else
 | 
						|
		return ""
 | 
						|
	end
 | 
						|
end
 | 
						|
 | 
						|
function get_gateway(interface)
 | 
						|
	local gateway = ""
 | 
						|
	local dump = nil
 | 
						|
 | 
						|
	dump = require("luci.util").ubus("network.interface.%s" % interface, "status", {})
 | 
						|
 | 
						|
	if dump and dump.route then
 | 
						|
		local _, route
 | 
						|
		for _, route in ipairs(dump.route) do
 | 
						|
			if dump.route[_].target == "0.0.0.0" then
 | 
						|
				gateway = dump.route[_].nexthop
 | 
						|
			end
 | 
						|
		end
 | 
						|
	end
 | 
						|
	if gateway == "" then
 | 
						|
		if dump and dump.inactive and dump.inactive.route then
 | 
						|
			local _, route
 | 
						|
			for _, route in ipairs(dump.inactive.route) do
 | 
						|
				if dump.inactive.route[_].target == "0.0.0.0" then
 | 
						|
					gateway = dump.inactive.route[_].nexthop
 | 
						|
				end
 | 
						|
			end
 | 
						|
		end
 | 
						|
	end
 | 
						|
	
 | 
						|
	if gateway == "" then
 | 
						|
		dump = require("luci.util").ubus("network.interface.%s_4" % interface, "status", {})
 | 
						|
 | 
						|
		if dump and dump.route then
 | 
						|
			local _, route
 | 
						|
			for _, route in ipairs(dump.route) do
 | 
						|
				if dump.route[_].target == "0.0.0.0" then
 | 
						|
					gateway = dump.route[_].nexthop
 | 
						|
				end
 | 
						|
			end
 | 
						|
		end
 | 
						|
		if gateway == "" then
 | 
						|
			if dump and dump.inactive and dump.inactive.route then
 | 
						|
				local _, route
 | 
						|
				for _, route in ipairs(dump.inactive.route) do
 | 
						|
					if dump.inactive.route[_].target == "0.0.0.0" then
 | 
						|
						gateway = dump.inactive.route[_].nexthop
 | 
						|
					end
 | 
						|
				end
 | 
						|
			end
 | 
						|
		end
 | 
						|
	end
 | 
						|
	return gateway
 | 
						|
end
 | 
						|
 | 
						|
-- This function come from OverTheBox by OVH with many changes
 | 
						|
-- Copyright 2015 OVH <OverTheBox@ovh.net>
 | 
						|
-- Simon Lelievre (simon.lelievre@corp.ovh.com)
 | 
						|
-- Sebastien Duponcheel <sebastien.duponcheel@ovh.net>
 | 
						|
-- Modified by Ycarus (Yannick Chabanois) <ycarus@zugaina.org> for OpenMPTCProuter project
 | 
						|
-- Under GPL3+
 | 
						|
function interfaces_status()
 | 
						|
	local ut      = require "luci.util"
 | 
						|
	local ntm     = require "luci.model.network".init()
 | 
						|
	local uci     = require "luci.model.uci".cursor()
 | 
						|
	local mArray = {}
 | 
						|
 | 
						|
	-- OpenMPTCProuter info
 | 
						|
	mArray.openmptcprouter = {}
 | 
						|
	--mArray.openmptcprouter["version"] = ut.trim(sys.exec("cat /etc/os-release | grep VERSION= | sed -e 's:VERSION=::'"))
 | 
						|
	mArray.openmptcprouter["version"] = uci:get("openmptcprouter", "settings", "version") or ut.trim(sys.exec("cat /etc/os-release | grep VERSION= | sed -e 's:VERSION=::' -e 's/^.//' -e 's/.$//'"))
 | 
						|
 | 
						|
	mArray.openmptcprouter["latest_version_omr"] = uci:get("openmptcprouter", "latest_versions", "omr") or ""
 | 
						|
	mArray.openmptcprouter["latest_version_vps"] = uci:get("openmptcprouter", "latest_versions", "vps") or ""
 | 
						|
	
 | 
						|
	mArray.openmptcprouter["service_addr"] = uci:get("shadowsocks-libev", "sss0", "server") or ""
 | 
						|
	local net = ntm:get_network("lan")
 | 
						|
	local ipaddr = net:ipaddr() or ""
 | 
						|
	mArray.openmptcprouter["local_addr"] = ipaddr
 | 
						|
	--mArray.openmptcprouter["local_addr"] = uci:get("network", "lan", "ipaddr")
 | 
						|
	mArray.openmptcprouter["hostname"] = "OpenMPTCProuter"
 | 
						|
	ucic:foreach("system", "system", function(s)
 | 
						|
		mArray.openmptcprouter["hostname"] = uci:get("system",s[".name"],"hostname") or "OpenMPTCProuter"
 | 
						|
	end)
 | 
						|
 | 
						|
	mArray.openmptcprouter["server_mptcp"] = ""
 | 
						|
	mArray.openmptcprouter["omr_time"] = os.time()
 | 
						|
	-- dns
 | 
						|
	mArray.openmptcprouter["dns"] = false
 | 
						|
	local dns_test = sys.exec("dig openmptcprouter.com | grep 'ANSWER: 0'")
 | 
						|
	if dns_test == "" then
 | 
						|
		mArray.openmptcprouter["dns"] = true
 | 
						|
	end
 | 
						|
 | 
						|
	mArray.openmptcprouter["ipv6"] = "disabled"
 | 
						|
	if uci:get("openmptcprouter","settings","disable_ipv6") ~= "1" then
 | 
						|
		mArray.openmptcprouter["ipv6"] = "enabled"
 | 
						|
	end
 | 
						|
 | 
						|
	mArray.openmptcprouter["ss_addr"] = ""
 | 
						|
	--mArray.openmptcprouter["ss_addr6"] = ""
 | 
						|
	mArray.openmptcprouter["wan_addr"] = ""
 | 
						|
	mArray.openmptcprouter["wan_addr6"] = ""
 | 
						|
	local tracker_ip = ""
 | 
						|
	local check_ipv4_website = uci:get("openmptcprouter","settings","check_ipv4_website") or "http://ip.openmptcprouter.com"
 | 
						|
	local check_ipv6_website = uci:get("openmptcprouter","settings","check_ipv6_website") or "http://ipv6.openmptcprouter.com"
 | 
						|
	if mArray.openmptcprouter["dns"] == true then
 | 
						|
		-- wanaddr
 | 
						|
		--mArray.openmptcprouter["wan_addr"] = uci:get("openmptcprouter","omr","public_detected_ipv4") or ""
 | 
						|
		
 | 
						|
		if uci:get("openmptcprouter","settings","external_check") ~= "0" then
 | 
						|
			timeout = uci:get("openmptcprouter","settings","status_getip_timeout") or "2"
 | 
						|
			mArray.openmptcprouter["wan_addr"] = ut.trim(sys.exec("wget -4 -qO- -T " .. timeout .. " " .. check_ipv4_website))
 | 
						|
			if mArray.openmptcprouter["wan_addr"] == "" then
 | 
						|
				mArray.openmptcprouter["wan_addr"] = ut.trim(sys.exec("dig TXT +timeout=" .. timeout .. " +short o-o.myaddr.l.google.com @ns1.google.com | awk -F'\"' '{print $2}'"))
 | 
						|
			end
 | 
						|
			if mArray.openmptcprouter["ipv6"] == "enabled" then
 | 
						|
				mArray.openmptcprouter["wan_addr6"] = uci:get("openmptcprouter","omr","public_detected_ipv6") or ""
 | 
						|
				if mArray.openmptcprouter["wan_addr6"] == "" then
 | 
						|
					mArray.openmptcprouter["wan_addr6"] = ut.trim(sys.exec("wget -6 -qO- -T " .. timeout .. " " .. check_ipv6_website))
 | 
						|
				end
 | 
						|
			end
 | 
						|
			mArray.openmptcprouter["external_check"] = true
 | 
						|
		else
 | 
						|
			mArray.openmptcprouter["external_check"] = false
 | 
						|
		end
 | 
						|
		-- shadowsocksaddr
 | 
						|
		mArray.openmptcprouter["ss_addr"] = uci:get("openmptcprouter","omr","detected_ss_ipv4") or ""
 | 
						|
		if mArray.openmptcprouter["ss_addr"] == "" then
 | 
						|
			tracker_ip = uci:get("shadowsocks-libev","tracker","local_address") or ""
 | 
						|
			if tracker_ip ~= "" then
 | 
						|
				local tracker_port = uci:get("shadowsocks-libev","tracker","local_port")
 | 
						|
				if uci:get("openmptcprouter","settings","external_check") ~= "0" then
 | 
						|
					mArray.openmptcprouter["ss_addr"] = ut.trim(sys.exec("curl -s -4 --socks5 " .. tracker_ip .. ":" .. tracker_port .. " -m " .. timeout .. " " .. check_ipv4_website))
 | 
						|
					--mArray.openmptcprouter["ss_addr6"] = sys.exec("curl -s -6 --socks5 " .. tracker_ip .. ":" .. tracker_port .. " -m 3 http://ipv6.openmptcprouter.com")
 | 
						|
				end
 | 
						|
			end
 | 
						|
		end
 | 
						|
	end
 | 
						|
 | 
						|
	if  mArray.openmptcprouter["service_addr"] ~= "" and mArray.openmptcprouter["service_addr"] ~= "127.0.0.1" then
 | 
						|
		mArray.openmptcprouter["vps_status"] = "DOWN"
 | 
						|
	else
 | 
						|
		mArray.openmptcprouter["vps_status"] = "UP"
 | 
						|
	end
 | 
						|
 | 
						|
	mArray.openmptcprouter["vps_admin"] = false
 | 
						|
	mArray.openmptcprouter["vps_admin_error"] = false
 | 
						|
	mArray.openmptcprouter["vps_admin_error_msg"] = "Not found"
 | 
						|
 | 
						|
	mArray.openmptcprouter["vps_hostname"] = "OpenMPTCProuter Server"
 | 
						|
	-- Get VPS info
 | 
						|
	ucic:foreach("openmptcprouter", "server", function(s)
 | 
						|
		local serverip = uci:get("openmptcprouter",s[".name"],"ip") or ""
 | 
						|
		local master = uci:get("openmptcprouter",s[".name"],"master") or "1"
 | 
						|
		if serverip ~= "" and (master == "1" or mArray.openmptcprouter["wan_addr"] == serverip) then
 | 
						|
			mArray.openmptcprouter["vps_omr_version"] = uci:get("openmptcprouter", s[".name"], "omr_version") or ""
 | 
						|
			mArray.openmptcprouter["vps_kernel"] = uci:get("openmptcprouter",s[".name"],"kernel") or ""
 | 
						|
			mArray.openmptcprouter["vps_machine"] = uci:get("openmptcprouter",s[".name"],"machine") or ""
 | 
						|
			timeout = uci:get("openmptcprouter","settings","status_vps_timeout") or "2"
 | 
						|
			if uci:get("openmptcprouter",s[".name"],"admin_error") == "1" then
 | 
						|
				mArray.openmptcprouter["vps_admin_error"] = true
 | 
						|
			end
 | 
						|
			local adminport = uci:get("openmptcprouter",s[".name"],"port") or "65500"
 | 
						|
			local token = uci:get("openmptcprouter",s[".name"],"token") or ""
 | 
						|
			if token ~= "" then
 | 
						|
				local vpsinfo_json = sys.exec('curl -4 --max-time ' .. timeout .. ' -s -k -H "Authorization: Bearer ' .. token .. '" https://' .. serverip .. ':' .. adminport .. '/status')
 | 
						|
				if vpsinfo_json ~= "" and vpsinfo_json ~= nil then
 | 
						|
					local status, vpsinfo = pcall(function() 
 | 
						|
						return json.decode(vpsinfo_json)
 | 
						|
					end)
 | 
						|
					if status and vpsinfo.vps ~= nil then
 | 
						|
						mArray.openmptcprouter["vps_loadavg"] = vpsinfo.vps.loadavg or ""
 | 
						|
						mArray.openmptcprouter["vps_uptime"] = vpsinfo.vps.uptime or ""
 | 
						|
						mArray.openmptcprouter["vps_mptcp"] = vpsinfo.vps.mptcp or ""
 | 
						|
						mArray.openmptcprouter["vps_hostname"] = vpsinfo.vps.hostname or ""
 | 
						|
						mArray.openmptcprouter["vps_time"] = vpsinfo.vps.time or ""
 | 
						|
						if vpsinfo.vps.time ~= "" then
 | 
						|
							if os.time() - vpsinfo.vps.time > 10 then
 | 
						|
								mArray.openmptcprouter["vps_time_accurate"] = false
 | 
						|
							else
 | 
						|
								mArray.openmptcprouter["vps_time_accurate"] = true
 | 
						|
							end
 | 
						|
						end
 | 
						|
						mArray.openmptcprouter["vps_admin"] = true
 | 
						|
						mArray.openmptcprouter["vps_status"] = "UP"
 | 
						|
						mArray.openmptcprouter["vps_admin_error_msg"] = ""
 | 
						|
					else
 | 
						|
						uci:set("openmptcprouter",s[".name"],"admin_error","1")
 | 
						|
						mArray.openmptcprouter["vps_admin_error"] = true
 | 
						|
						uci:delete("openmptcprouter",s[".name"],"token")
 | 
						|
						uci:save("openmptcprouter",s[".name"])
 | 
						|
						uci:commit("openmptcprouter",s[".name"])
 | 
						|
						mArray.openmptcprouter["vps_admin"] = false
 | 
						|
						mArray.openmptcprouter["vps_admin_error_msg"] = "Answer error"
 | 
						|
					end
 | 
						|
				else
 | 
						|
					mArray.openmptcprouter["vps_admin"] = false
 | 
						|
					mArray.openmptcprouter["vps_admin_error_msg"] = "No answer"
 | 
						|
				end
 | 
						|
			else
 | 
						|
				mArray.openmptcprouter["vps_admin"] = false
 | 
						|
				mArray.openmptcprouter["vps_admin_error_msg"] = "No token"
 | 
						|
			end
 | 
						|
		end
 | 
						|
	end)
 | 
						|
 | 
						|
 | 
						|
	if mArray.openmptcprouter["vps_hostname"] == "" then
 | 
						|
		mArray.openmptcprouter["vps_hostname"] = "Server"
 | 
						|
	end
 | 
						|
	-- Check openmptcprouter service are running
 | 
						|
	mArray.openmptcprouter["tun_service"] = false
 | 
						|
	mArray.openmptcprouter["tun_state"] = ""
 | 
						|
	mArray.openmptcprouter["tun6_state"] = ""
 | 
						|
	if string.find(sys.exec("/usr/bin/pgrep '^(/usr/sbin/)?glorytun(-udp)?$'"), "%d+") or string.find(sys.exec("/usr/bin/pgrep '^(/usr/sbin/)?dsvpn?$'"), "%d+") or string.find(sys.exec("/usr/bin/pgrep '^(/usr/sbin/)?mlvpn?$'"), "%d+") or string.find(sys.exec("/usr/bin/pgrep '^(/usr/sbin/)?openvpn?$'"), "%d+") then
 | 
						|
		mArray.openmptcprouter["tun_service"] = true
 | 
						|
		mArray.openmptcprouter["tun_ip"] = get_ip("omrvpn")
 | 
						|
		local tun_dev = uci:get("network","omrvpn","ifname")
 | 
						|
		if tun_dev == "" then
 | 
						|
			tun_dev = get_device("omrvpn")
 | 
						|
		end
 | 
						|
		if tun_dev ~= "" and tun_dev ~= nil then
 | 
						|
			local peer = get_gateway("omrvpn")
 | 
						|
			if peer == "" then
 | 
						|
				peer = ut.trim(sys.exec("ip -4 r list dev " .. tun_dev .. " | grep kernel | awk '/proto kernel/ {print $1}' | grep -v / | tr -d '\n'"))
 | 
						|
			end
 | 
						|
			if peer ~= "" then
 | 
						|
				local tunnel_ping_test = ut.trim(sys.exec("ping -w 1 -c 1 -I " .. tun_dev .. " " .. peer .. " | grep '100% packet loss'"))
 | 
						|
				if tunnel_ping_test == "" then
 | 
						|
					mArray.openmptcprouter["tun_state"] = "UP"
 | 
						|
				else
 | 
						|
					mArray.openmptcprouter["tun_state"] = "DOWN"
 | 
						|
				end
 | 
						|
				if mArray.openmptcprouter["ipv6"] == "enabled" then
 | 
						|
					local tunnel_ping6_test = ut.trim(sys.exec("ping6 -w 1 -c 1 fe80::a00:1%6in4-omr6in4 | grep '100% packet loss'"))
 | 
						|
					if tunnel_ping6_test == "" then
 | 
						|
						mArray.openmptcprouter["tun6_state"] = "UP"
 | 
						|
					else
 | 
						|
						mArray.openmptcprouter["tun6_state"] = "DOWN"
 | 
						|
					end
 | 
						|
				end
 | 
						|
			else
 | 
						|
				mArray.openmptcprouter["tun_state"] = "DOWN"
 | 
						|
				mArray.openmptcprouter["tun6_state"] = "DOWN"
 | 
						|
			end
 | 
						|
		end
 | 
						|
	elseif uci:get("openmptcprouter","settings","vpn") == "none" then
 | 
						|
		mArray.openmptcprouter["tun_service"] = true
 | 
						|
	end
 | 
						|
	
 | 
						|
	-- check Shadowsocks is running
 | 
						|
	mArray.openmptcprouter["socks_service"] = false
 | 
						|
	if string.find(sys.exec("/usr/bin/pgrep ss-redir"), "%d+") then
 | 
						|
		mArray.openmptcprouter["socks_service"] = true
 | 
						|
	end
 | 
						|
 | 
						|
	mArray.openmptcprouter["socks_service_enabled"] = true
 | 
						|
	local ss_server = uci:get("shadowsocks-libev","sss0","disabled") or "0"
 | 
						|
	if ss_server == "1" then
 | 
						|
		mArray.openmptcprouter["socks_service_enabled"] = false
 | 
						|
	end
 | 
						|
	local ss_key = uci:get("shadowsocks-libev","sss0","key") or ""
 | 
						|
	mArray.openmptcprouter["socks_service_method"] = uci:get("shadowsocks-libev","sss0","method")
 | 
						|
	if ss_key == "" then
 | 
						|
		mArray.openmptcprouter["socks_service_key"] = false
 | 
						|
	else
 | 
						|
		mArray.openmptcprouter["socks_service_key"] = true
 | 
						|
	end
 | 
						|
 | 
						|
	-- Add DHCP infos by parsing dnsmasq config file
 | 
						|
	mArray.openmptcprouter.dhcpd = {}
 | 
						|
	dnsmasq = ut.trim(sys.exec("cat /var/etc/dnsmasq.conf*"))
 | 
						|
	for itf, range_start, range_end, mask, leasetime in dnsmasq:gmatch("range=[%w,!:-]*set:(%w+),(%d+\.%d+\.%d+\.%d+),(%d+\.%d+\.%d+\.%d+),(%d+\.%d+\.%d+\.%d+),(%w+)") do
 | 
						|
		mArray.openmptcprouter.dhcpd[itf] = {}
 | 
						|
		mArray.openmptcprouter.dhcpd[itf].interface = itf
 | 
						|
		mArray.openmptcprouter.dhcpd[itf].range_start = range_start
 | 
						|
		mArray.openmptcprouter.dhcpd[itf].range_end = range_end
 | 
						|
		mArray.openmptcprouter.dhcpd[itf].netmask = mask
 | 
						|
		mArray.openmptcprouter.dhcpd[itf].leasetime = leasetime
 | 
						|
		mArray.openmptcprouter.dhcpd[itf].router = mArray.openmptcprouter["local_addr"]
 | 
						|
		mArray.openmptcprouter.dhcpd[itf].dns = mArray.openmptcprouter["local_addr"]
 | 
						|
	end
 | 
						|
	for itf, option, value in dnsmasq:gmatch("option=(%w+),([%w:-]+),(%d+\.%d+\.%d+\.%d+)") do
 | 
						|
		if mArray.openmptcprouter.dhcpd[itf] then
 | 
						|
			if option == "option:router" or option == "3" then
 | 
						|
				mArray.openmptcprouter.dhcpd[itf].router = value
 | 
						|
			end
 | 
						|
			if option == "option:dns-server" or option == "6" then
 | 
						|
				mArray.openmptcprouter.dhcpd[itf].dns = value
 | 
						|
			end
 | 
						|
		end
 | 
						|
	end
 | 
						|
 | 
						|
 | 
						|
	-- Parse mptcp kernel info
 | 
						|
	local mptcp = {}
 | 
						|
	local fullmesh = ut.trim(sys.exec("cat /proc/net/mptcp_fullmesh"))
 | 
						|
	for ind, addressId, backup, ipaddr in fullmesh:gmatch("(%d+), (%d+), (%d+), (%d+\.%d+\.%d+\.%d+)") do
 | 
						|
		mptcp[ipaddr] = {}
 | 
						|
		mptcp[ipaddr].index = ind
 | 
						|
		mptcp[ipaddr].id    = addressId
 | 
						|
		mptcp[ipaddr].backup= backup
 | 
						|
		mptcp[ipaddr].ipaddr= ipaddr
 | 
						|
	end
 | 
						|
 | 
						|
 | 
						|
	mArray.openmptcprouter['model'] = sys.exec("ubus call system board | jsonfilter -q -e '@.model' 2>/dev/null | tr -d '\n'")
 | 
						|
	local board_name = sys.exec("ubus call system board | jsonfilter -q -e '@.board_name' 2>/dev/null | tr -d '\n'")
 | 
						|
	-- retrieve core temperature
 | 
						|
	if board_name:match("^raspberrypi.*") then
 | 
						|
		mArray.openmptcprouter["core_temp"] = sys.exec("cat /sys/class/thermal/thermal_zone0/temp 2>/dev/null"):match("%d+")
 | 
						|
	end
 | 
						|
	mArray.openmptcprouter["loadavg"] = sys.exec("cat /proc/loadavg 2>/dev/null"):match("[%d%.]+ [%d%.]+ [%d%.]+")
 | 
						|
	mArray.openmptcprouter["uptime"] = sys.exec("cat /proc/uptime 2>/dev/null"):match("[%d%.]+")
 | 
						|
 | 
						|
	mArray.openmptcprouter["fstype"] = sys.exec("cat /proc/mounts 2>/dev/null | awk '/\\/dev\\/root/ {print $3}' | tr -d '\n'")
 | 
						|
	if mArray.openmptcprouter["fstype"] == "ext4" then
 | 
						|
		if sys.exec("cat /proc/mounts 2>/dev/null | awk '/\\/dev\\/root/ {print $4}' | grep ro") == "" then
 | 
						|
			mArray.openmptcprouter["fsro"] = false
 | 
						|
		else
 | 
						|
			mArray.openmptcprouter["fsro"] = true
 | 
						|
		end
 | 
						|
	elseif mArray.openmptcprouter["fstype"] == "squashfs" then
 | 
						|
		if sys.exec("cat /proc/mounts 2>/dev/null | awk '/overlayfs/ {print $4}' | grep overlay") == "" then
 | 
						|
			mArray.openmptcprouter["fsro"] = true
 | 
						|
		else
 | 
						|
			mArray.openmptcprouter["fsro"] = false
 | 
						|
		end
 | 
						|
	end
 | 
						|
 | 
						|
	-- overview status
 | 
						|
	mArray.wans = {}
 | 
						|
	mArray.tunnels = {}
 | 
						|
	allintf = {}
 | 
						|
 | 
						|
	uci:foreach("network", "interface", function (section)
 | 
						|
	    local interface = section[".name"]
 | 
						|
	    local net = ntm:get_network(interface)
 | 
						|
	    local ipaddr = net:ipaddr() or ""
 | 
						|
	    local gateway = section["gateway"] or ""
 | 
						|
	    local multipath = section["multipath"]
 | 
						|
	    local enabled = section["auto"]
 | 
						|
 | 
						|
	    --if not ipaddr or not gateway then return end
 | 
						|
	    -- Don't show if0 in the overview
 | 
						|
	    --if interface == "lo" then return end
 | 
						|
 | 
						|
	    local ifname = get_device(interface)
 | 
						|
	    if ifname == "" or ifname == nil then
 | 
						|
		ifname = section["ifname"] or ""
 | 
						|
	    end
 | 
						|
	    --if ifname ~= nil and ifname:match("^tun.*") and interface:match("^ovpn.*") then
 | 
						|
	    --ifname = get_device(interface:sub(5))
 | 
						|
	    --end
 | 
						|
	    
 | 
						|
	    duplicateif = false
 | 
						|
	    if ifname ~= "" and ifname ~= nil then
 | 
						|
		if allintf[ifname] then
 | 
						|
		    connectivity = "ERROR"
 | 
						|
		    duplicateif = true
 | 
						|
		else
 | 
						|
		    allintf[ifname] = true
 | 
						|
		end
 | 
						|
	    end
 | 
						|
 | 
						|
	    --if multipath == "off" and not ifname:match("^tun.*") then return end
 | 
						|
	    if multipath == "off" then return end
 | 
						|
	    
 | 
						|
	    if enabled == "0" then return end
 | 
						|
 | 
						|
	    local connectivity
 | 
						|
	    local multipath_state = ""
 | 
						|
	    local current_multipath_state = ""
 | 
						|
	    if ifname ~= "" and ifname ~= nil then
 | 
						|
		    if fs.access("/sys/class/net/" .. ifname) then
 | 
						|
			    multipath_state = ut.trim(sys.exec("multipath " .. ifname .. " | grep deactivated"))
 | 
						|
			    if multipath_state == "" then
 | 
						|
				connectivity = "OK"
 | 
						|
			    else
 | 
						|
				connectivity = "ERROR"
 | 
						|
			    end
 | 
						|
		    else
 | 
						|
			    connectivity = "ERROR"
 | 
						|
		    end
 | 
						|
	    else
 | 
						|
		    connectivity = "ERROR"
 | 
						|
	    end
 | 
						|
	    if ifname ~= "" and ifname ~= nil then
 | 
						|
		    local test_current_multipath_state = ut.trim(sys.exec("multipath " .. ifname))
 | 
						|
		    if string.find(test_current_multipath_state,"deactivated") then
 | 
						|
			    current_multipath_state = "off"
 | 
						|
		    elseif string.find(test_current_multipath_state,"default") then
 | 
						|
			    current_multipath_state = "on"
 | 
						|
		    elseif string.find(test_current_multipath_state,"backup") then
 | 
						|
			    current_multipath_state = "backup"
 | 
						|
		    elseif string.find(test_current_multipath_state,"handover") then
 | 
						|
			    current_multipath_state = "handover"
 | 
						|
		    else
 | 
						|
			    current_multipath_state = ""
 | 
						|
		    end
 | 
						|
	    end
 | 
						|
	    if ipaddr == "" and ifname ~= nil and ifname ~= "" then
 | 
						|
		    ipaddr = ut.trim(sys.exec("ip -4 -br addr ls dev " .. ifname .. " | awk -F'[ /]+' '{print $3}' | tr -d '\n'"))
 | 
						|
	    end
 | 
						|
	    if ipaddr == "" and ifname ~= nil and ifname ~= "" then
 | 
						|
		    ipaddr = ut.trim(sys.exec("ip -4 addr show dev " .. ifname .. " | grep -m 1 inet | awk '{print $2}' | cut -d'/' -s -f1 | tr -d '\n'"))
 | 
						|
	    end
 | 
						|
	    if ipaddr == "" then
 | 
						|
		    connectivity = "ERROR"
 | 
						|
	    end
 | 
						|
 | 
						|
	    -- Detect WAN gateway status
 | 
						|
	    local gw_ping = "UP"
 | 
						|
	    if ifname ~= nil and ifname:match("^tun.*") and interface:match("^ovpn.*") then
 | 
						|
		gateway = ut.trim(sys.exec("ip -4 r list dev " .. ifname .. " | grep via | grep -v default | grep -v metric | awk '{print $1}' | tr -d '\n'"))
 | 
						|
	    end
 | 
						|
 | 
						|
	    if gateway == "" then
 | 
						|
		    gateway = get_gateway(interface)
 | 
						|
	    end
 | 
						|
	    if gateway == "" and ifname ~= nil and ifname ~= "" then
 | 
						|
		    if fs.access("/sys/class/net/" .. ifname) then
 | 
						|
			    gateway = ut.trim(sys.exec("ip -4 r list dev " .. ifname .. " | grep kernel | awk '/proto kernel/ {print $1}' | grep -v / | tr -d '\n'"))
 | 
						|
			    if gateway == "" then
 | 
						|
				gateway = ut.trim(sys.exec("ip -4 r list dev " .. ifname .. " | grep default | awk '{print $3}' | tr -d '\n'"))
 | 
						|
			    end
 | 
						|
		    end
 | 
						|
	    end
 | 
						|
	    if gateway ~= "" and uci:get("openmptcprouter", "settings", "disablegwping") ~= "1" then
 | 
						|
		    local gw_ping_test = ut.trim(sys.exec("ping -w 1 -c 1 " .. gateway .. " | grep '100% packet loss'"))
 | 
						|
		    if gw_ping_test ~= "" then
 | 
						|
			    gw_ping = "DOWN"
 | 
						|
			    if connectivity == "OK" then
 | 
						|
				    connectivity = "WARNING"
 | 
						|
			    end
 | 
						|
		    end
 | 
						|
	    elseif gateway == "" then
 | 
						|
		    gw_ping = "DOWN"
 | 
						|
		    connectivity = "ERROR"
 | 
						|
	    end
 | 
						|
 | 
						|
	    local latency = ""
 | 
						|
	    local server_ping = ""
 | 
						|
	    --if connectivity ~= "ERROR" and ifname ~= "" and gateway ~= "" and gw_ping ~= "DOWN" and ifname ~= nil and mArray.openmptcprouter["service_addr"] ~= "" and ipaddr ~= "" then
 | 
						|
	    if ifname ~= "" and gateway ~= "" and gw_ping ~= "DOWN" and ifname ~= nil and mArray.openmptcprouter["service_addr"] ~= "" and ipaddr ~= "" then
 | 
						|
		    local serverip = mArray.openmptcprouter["service_addr"]
 | 
						|
		    if serverip == "127.0.0.1" then
 | 
						|
			    serverip = mArray.openmptcprouter["wan_addr"]
 | 
						|
		    end
 | 
						|
		    if serverip ~= "" and uci:get("openmptcprouter", "settings", "disableserverping") ~= "1" then
 | 
						|
			    local server_ping_test = sys.exec("ping -B -w 1 -c 1 -I " .. ifname .. " " .. serverip)
 | 
						|
			    local server_ping_result = ut.trim(sys.exec("echo '" .. server_ping_test .. "' | grep '100% packet loss'"))
 | 
						|
			    if server_ping_result ~= "" then
 | 
						|
				    server_ping = "DOWN"
 | 
						|
				    if connectivity == "OK" then
 | 
						|
					    connectivity = "WARNING"
 | 
						|
				    end
 | 
						|
			    else
 | 
						|
				    mArray.openmptcprouter["vps_status"] = "UP"
 | 
						|
				    server_ping = "UP"
 | 
						|
				    latency = ut.trim(sys.exec("echo '" .. server_ping_test .. "' | cut -d '/' -s -f5 | cut -d '.' -f1"))
 | 
						|
			    end
 | 
						|
		    end
 | 
						|
	    end
 | 
						|
 | 
						|
	    local multipath_available
 | 
						|
	    if connectivity ~= "ERROR" and mArray.openmptcprouter["dns"] == true and ifname ~= nil and ifname ~= "" and gateway ~= "" and gw_ping == "UP" then
 | 
						|
		    -- Test if multipath can work on the connection
 | 
						|
		    local multipath_available_state = uci:get("openmptcprouter",interface,"mptcp_status") or ""
 | 
						|
		    if multipath_available_state == "" then
 | 
						|
			    --if mArray.openmptcprouter["service_addr"] ~= "" then
 | 
						|
			    --    multipath_available_state = ut.trim(sys.exec("omr-tracebox-mptcp " .. mArray.openmptcprouter["service_addr"] .. " " .. ifname .. " | grep 'MPTCP disabled'"))
 | 
						|
			    --else
 | 
						|
				    multipath_available_state = ut.trim(sys.exec("omr-mptcp-intf " .. ifname .. " | grep 'Nay, Nay, Nay'"))
 | 
						|
			    --end
 | 
						|
		    else
 | 
						|
			    multipath_available_state = ut.trim(sys.exec("echo '" .. multipath_available_state .. "' | grep 'MPTCP disabled'"))
 | 
						|
		    end
 | 
						|
		    if multipath_available_state == "" then
 | 
						|
			    multipath_available = "OK"
 | 
						|
		    else
 | 
						|
			    multipath_available_state_wan = ut.trim(sys.exec("omr-mptcp-intf " .. ifname .. " | grep 'Nay, Nay, Nay'"))
 | 
						|
			    if multipath_available_state_wan == "" then
 | 
						|
				    multipath_available = "OK"
 | 
						|
				    if mArray.openmptcprouter["service_addr"] ~= "" and mArray.openmptcprouter["service_addr"] ~= "127.0.0.1" then
 | 
						|
					    mArray.openmptcprouter["server_mptcp"] = "disabled"
 | 
						|
				    end
 | 
						|
			    else
 | 
						|
				    multipath_available = "ERROR"
 | 
						|
				    connectivity = "WARNING"
 | 
						|
			    end
 | 
						|
		    end
 | 
						|
	    else
 | 
						|
		    multipath_available = "NO CHECK"
 | 
						|
	    end
 | 
						|
 | 
						|
	    
 | 
						|
	    -- Detect if WAN get an IPv6
 | 
						|
	    local ipv6_discover = "NONE"
 | 
						|
	    if ifname ~= "" and ifname ~= nil and mArray.openmptcprouter["ipv6"] == "enabled" then
 | 
						|
		    local ipv6_result = ""
 | 
						|
		    local ipv6_result = _ipv6_discover(ifname)
 | 
						|
		    if type(ipv6_result) == "table" and #ipv6_result > 0 then
 | 
						|
			    local ipv6_addr_test
 | 
						|
			    for k,v in ipairs(ipv6_result) do
 | 
						|
				    if v.RecursiveDnsServer then
 | 
						|
					    if type(v.RecursiveDnsServer) ~= "table" then
 | 
						|
						    ipv6_addr_test = sys.exec("ip -6 addr | grep " .. v.RecursiveDnsServer)
 | 
						|
						    if ipv6_addr_test == "" then
 | 
						|
							    ipv6_discover = "DETECTED"
 | 
						|
							    --if connectivity == "OK" then
 | 
						|
							    --    connectivity = "WARNING"
 | 
						|
							    --end
 | 
						|
						    end
 | 
						|
					    end
 | 
						|
				    end
 | 
						|
			    end
 | 
						|
		    end
 | 
						|
	    end
 | 
						|
 | 
						|
	    local publicIP = ""
 | 
						|
	    local whois = ""
 | 
						|
	    if ifname ~= nil and ifname:match("^tun.*") and interface:match("^ovpn.*") then
 | 
						|
		    publicIP = uci:get("openmptcprouter",interface:sub(5),"publicip") or ""
 | 
						|
		    if ifname ~= nil and publicIP == "" and uci:get("openmptcprouter","settings","external_check") ~= "0" then
 | 
						|
			    publicIP = ut.trim(sys.exec("omr-ip-intf " .. get_device(interface:sub(5))))
 | 
						|
		    end
 | 
						|
	    else
 | 
						|
		    publicIP = uci:get("openmptcprouter",interface,"publicip") or ""
 | 
						|
		    if ifname ~= nil and publicIP == "" and uci:get("openmptcprouter","settings","external_check") ~= "0" then
 | 
						|
			    publicIP = ut.trim(sys.exec("omr-ip-intf " .. ifname))
 | 
						|
		    end
 | 
						|
	    end
 | 
						|
	    
 | 
						|
	    whois = ""
 | 
						|
	    if publicIP ~= "" then
 | 
						|
		    whois = uci:get("openmptcprouter",interface,"asn") or ""
 | 
						|
		    if whois == "" and uci:get("openmptcprouter","settings","external_check") ~= "0" then
 | 
						|
			    --whois = ut.trim(sys.exec("whois " .. publicIP .. " | grep -i 'netname' | awk '{print $2}'"))
 | 
						|
			    whois = ut.trim(sys.exec("wget -4 -qO- -T 1 'http://api.iptoasn.com/v1/as/ip/" .. publicIP .. "' | jsonfilter -q -e '@.as_description'"))
 | 
						|
		    end
 | 
						|
	    end
 | 
						|
	    
 | 
						|
	    local mtu = ""
 | 
						|
	    if ifname ~= "" and ifname ~= nil then
 | 
						|
		    if fs.access("/sys/class/net/" .. ifname) then
 | 
						|
			    mtu = ut.trim(sys.exec("cat /sys/class/net/" .. ifname .. "/mtu | tr -d '\n'"))
 | 
						|
			    if mtu == "" and interface ~= nil then
 | 
						|
					mtu = uci:get("openmptcprouter",interface,"mtu") or ""
 | 
						|
			    end
 | 
						|
		    end
 | 
						|
	    end
 | 
						|
 | 
						|
	    local data = {
 | 
						|
		label = section["label"] or interface,
 | 
						|
		name = interface,
 | 
						|
		--link = net:adminlink() or "",
 | 
						|
		ifname = ifname,
 | 
						|
		ipaddr = ipaddr,
 | 
						|
		gateway = gateway,
 | 
						|
		multipath = section["multipath"],
 | 
						|
		status = connectivity,
 | 
						|
		wanip = publicIP,
 | 
						|
		latency = latency,
 | 
						|
		mtu = mtu,
 | 
						|
		whois = whois or "unknown",
 | 
						|
		qos = section["trafficcontrol"],
 | 
						|
		download = section["download"],
 | 
						|
		upload = section["upload"],
 | 
						|
		gw_ping = gw_ping,
 | 
						|
		server_ping = server_ping,
 | 
						|
		ipv6_discover = ipv6_discover,
 | 
						|
		multipath_available = multipath_available,
 | 
						|
		multipath_state = current_multipath_state,
 | 
						|
		duplicateif = duplicateif,
 | 
						|
	    }
 | 
						|
	    if ifname ~= nil and ifname:match("^tun.*") then
 | 
						|
		    table.insert(mArray.tunnels, data);
 | 
						|
	    elseif ifname ~= nil and ifname:match("^mlvpn.*") then
 | 
						|
		    table.insert(mArray.tunnels, data);
 | 
						|
	    else
 | 
						|
		    table.insert(mArray.wans, data);
 | 
						|
	    end
 | 
						|
	end)
 | 
						|
 | 
						|
	--luci.http.prepare_content("application/json")
 | 
						|
	--luci.http.write_json(mArray)
 | 
						|
	return mArray
 | 
						|
	--return "titi"
 | 
						|
end
 | 
						|
 | 
						|
-- This come from OverTheBox by OVH
 | 
						|
-- Copyright 2015 OVH <OverTheBox@ovh.net>
 | 
						|
-- Simon Lelievre (simon.lelievre@corp.ovh.com)
 | 
						|
-- Sebastien Duponcheel <sebastien.duponcheel@ovh.net>
 | 
						|
-- Under GPL3+
 | 
						|
function _ipv6_discover(interface)
 | 
						|
	local result = {}
 | 
						|
 | 
						|
	--local ra6_list = (sys.exec("rdisc6 -nm " .. interface))
 | 
						|
	local ra6_list = (sys.exec("rdisc6 -n1 -r1 " .. interface))
 | 
						|
	-- dissect results
 | 
						|
	local lines = {}
 | 
						|
	local index = {}
 | 
						|
	ra6_list:gsub('[^\r\n]+', function(c)
 | 
						|
	    table.insert(lines, c)
 | 
						|
	    if c:match("Hop limit") then
 | 
						|
		    table.insert(index, #lines)
 | 
						|
	    end
 | 
						|
	end)
 | 
						|
	local ra6_result = {}
 | 
						|
	for k,v in ipairs(index) do
 | 
						|
		local istart = v
 | 
						|
		local iend = index[k+1] or #lines
 | 
						|
 | 
						|
		local entry = {}
 | 
						|
		for i=istart,iend - 1 do
 | 
						|
			local level = lines[i]:find('%w')
 | 
						|
			local line = lines[i]:sub(level)
 | 
						|
 | 
						|
			local param, value
 | 
						|
			if line:match('^from') then
 | 
						|
				param, value = line:match('(from)%s+(.*)$')
 | 
						|
			else
 | 
						|
				param, value = line:match('([^:]+):(.*)$')
 | 
						|
				-- Capitalize param name and remove spaces
 | 
						|
				param = param:gsub("(%a)([%w_']*)", function(first, rest) return first:upper()..rest:lower() end):gsub("[%s-]",'')
 | 
						|
				param = param:gsub("%.$", '')
 | 
						|
				-- Remove text between brackets, seconds and spaces
 | 
						|
				value = value:lower()
 | 
						|
				value = value:gsub("%(.*%)", '')
 | 
						|
				value = value:gsub("%s-seconds%s-", '')
 | 
						|
				value = value:gsub("^%s+", '')
 | 
						|
				value = value:gsub("%s+$", '')
 | 
						|
			end
 | 
						|
 | 
						|
			if entry[param] == nil then
 | 
						|
				entry[param] = value
 | 
						|
			elseif type(entry[param]) == "table" then
 | 
						|
				table.insert(entry[param], value)
 | 
						|
			else
 | 
						|
				old = entry[param]
 | 
						|
				entry[param] = {}
 | 
						|
				table.insert(entry[param], old)
 | 
						|
				table.insert(entry[param], value)
 | 
						|
			end
 | 
						|
		end
 | 
						|
		table.insert(ra6_result, entry)
 | 
						|
	end
 | 
						|
	return ra6_result
 | 
						|
end
 | 
						|
 | 
						|
local methods = {
 | 
						|
	status = {
 | 
						|
		call = function()
 | 
						|
			return interfaces_status()
 | 
						|
		end
 | 
						|
	},
 | 
						|
	setIPv6 = {
 | 
						|
		args = { disable = 0 },
 | 
						|
		call = function(args)
 | 
						|
			set_ipv6_state(args.disable)
 | 
						|
		end
 | 
						|
	},
 | 
						|
	updateVPS = {
 | 
						|
		call = function()
 | 
						|
			update_vps()
 | 
						|
		end
 | 
						|
	},
 | 
						|
	redirectports = {
 | 
						|
		args = { server = "", redirect_ports = 0},
 | 
						|
		call = function(args)
 | 
						|
			redirectports(args.server,args.redirect_ports)
 | 
						|
		end
 | 
						|
	},
 | 
						|
	tcpkeepalivetime = {
 | 
						|
		args = { tcp_keepalive_time = 7200 },
 | 
						|
		call = function(args)
 | 
						|
			tcpkeepalivetime(args.tcp_keepalive_time)
 | 
						|
		end
 | 
						|
	},
 | 
						|
	tcpfintimeout = {
 | 
						|
		args = { tcp_fin_timeout = 60 },
 | 
						|
		call = function(args)
 | 
						|
			tcpfintimeout(args.tcp_fin_timeout)
 | 
						|
		end
 | 
						|
	},
 | 
						|
	tcpsynretries = {
 | 
						|
		args = { tcp_syn_retries = 3 },
 | 
						|
		call = function(args)
 | 
						|
			tcpsynretries(args.tcp_syn_retries)
 | 
						|
		end
 | 
						|
	},
 | 
						|
	tcpfastopen = {
 | 
						|
		args = { tcp_fastopen = 1},
 | 
						|
		call = function(args)
 | 
						|
			tcpfastopen(args.tcp_fastopen)
 | 
						|
		end
 | 
						|
	},
 | 
						|
	disableipv6 = {
 | 
						|
		args = { disable_ipv6 = 0 },
 | 
						|
		call = function(args)
 | 
						|
			set_ipv6_disable(args.disable_ipv6)
 | 
						|
		end
 | 
						|
	},
 | 
						|
	externalcheck = {
 | 
						|
		args = { externalcheck = 0 },
 | 
						|
		call = function(args)
 | 
						|
			externalcheck(args.externalcheck)
 | 
						|
		end
 | 
						|
	},
 | 
						|
	savevnstat = {
 | 
						|
		args = { savevnstat = 0 },
 | 
						|
		call = function(args)
 | 
						|
			savevnstat(args.savevnstat)
 | 
						|
		end
 | 
						|
	},
 | 
						|
	disablefastopen = {
 | 
						|
		args = { disablefastopen = 0 },
 | 
						|
		call = function(args)
 | 
						|
			disablefastopen(args.disablefastopen)
 | 
						|
		end
 | 
						|
	},
 | 
						|
	enableobfs = {
 | 
						|
		args = { enableobfs = 0 },
 | 
						|
		call = function(args)
 | 
						|
			enableobfs(args.enableobfs)
 | 
						|
		end
 | 
						|
	},
 | 
						|
	setmastertype = {
 | 
						|
		args = { master_type = "redundant" },
 | 
						|
		call = function(args)
 | 
						|
			setmastertype(args.setmastertype)
 | 
						|
		end
 | 
						|
	},
 | 
						|
	cpuscalingmin = {
 | 
						|
		args = { scaling_min_freq = 0 },
 | 
						|
		call = function(args)
 | 
						|
			cpuscalingmin(args.scaling_min_freq)
 | 
						|
		end
 | 
						|
	},
 | 
						|
	cpuscalingmax = {
 | 
						|
		args = { scaling_max_freq = 0 },
 | 
						|
		call = function(args)
 | 
						|
			cpuscalingmax(args.scaling_max_freq)
 | 
						|
		end
 | 
						|
	},
 | 
						|
	addserver = {
 | 
						|
		args = { server_name = "" },
 | 
						|
		call = function(args)
 | 
						|
			add_server(args.server_name)
 | 
						|
		end
 | 
						|
	},
 | 
						|
	removeserver = {
 | 
						|
		args = { server_name = "" },
 | 
						|
		call = function(args)
 | 
						|
			remove_server(args.server_name)
 | 
						|
		end
 | 
						|
	},
 | 
						|
	addinterface = {
 | 
						|
		args = { ifname = "" },
 | 
						|
		call = function(args)
 | 
						|
			add_interface(args.ifname)
 | 
						|
		end
 | 
						|
	},
 | 
						|
	removeinterface = {
 | 
						|
		args = { intf = "" },
 | 
						|
		call = function(args)
 | 
						|
			remove_interface(args.intf)
 | 
						|
		end
 | 
						|
	},
 | 
						|
	setinterface = {
 | 
						|
		args = { intf = "", proto = "dhcp", ipaddr = "", netmask = "", gateway = "", sqmenabled = 0, downloadspeed = 0, uploadspeed = 0 },
 | 
						|
		call = function(args)
 | 
						|
			set_interface(args.intf, args.proto, args.ipaddr, args.netmask, args.gateway, args.sqmenabled, args.downloadspeed, args.uploadspeed)
 | 
						|
		end
 | 
						|
	},
 | 
						|
	defaultvpn = {
 | 
						|
		args = { vpn = "glorytun-tcp" },
 | 
						|
		call = function(args)
 | 
						|
			default_vpn(args.vpn)
 | 
						|
		end
 | 
						|
	},
 | 
						|
	setserver = {
 | 
						|
		args = { server = "vps", server_ip = "", openmptcprouter_vps_key = "" },
 | 
						|
		call = function(args)
 | 
						|
			server_settings(args.server, args.server_ip, args.openmptcprouter_vps_key)
 | 
						|
		end
 | 
						|
	},
 | 
						|
	setshadowsocks = {
 | 
						|
		args = { key = "" },
 | 
						|
		call = function(args)
 | 
						|
			set_shadowsocks(args.shadowsocks_key)
 | 
						|
		end
 | 
						|
	},
 | 
						|
	disableshadowsocks = {
 | 
						|
		args = { disable = 0 },
 | 
						|
		call = function(args)
 | 
						|
			disable_shadowsocks(args.disable)
 | 
						|
		end
 | 
						|
	},
 | 
						|
	setglorytun = {
 | 
						|
		args = { key = "" },
 | 
						|
		call = function(args)
 | 
						|
			set_glorytun(args.key)
 | 
						|
		end
 | 
						|
	},
 | 
						|
	setdsvpn = {
 | 
						|
		args = { key = "" },
 | 
						|
		call = function(args)
 | 
						|
			set_dsvpn(args.key)
 | 
						|
		end
 | 
						|
	},
 | 
						|
	setmlvpn = {
 | 
						|
		args = { key = "" },
 | 
						|
		call = function(args)
 | 
						|
			set_mlvpn(args.key)
 | 
						|
		end
 | 
						|
	},
 | 
						|
	setopenvpn = {
 | 
						|
		args = { key = "" },
 | 
						|
		call = function(args)
 | 
						|
			set_openvpn(args.key)
 | 
						|
		end
 | 
						|
	},
 | 
						|
	
 | 
						|
}
 | 
						|
 | 
						|
local function parseInput()
 | 
						|
	local parse = jsonc.new()
 | 
						|
	local done, err
 | 
						|
 | 
						|
	while true do
 | 
						|
		local chunk = io.read(4096)
 | 
						|
		if not chunk then
 | 
						|
			break
 | 
						|
		elseif not done and not err then
 | 
						|
			done, err = parse:parse(chunk)
 | 
						|
		end
 | 
						|
	end
 | 
						|
 | 
						|
	if not done then
 | 
						|
		print(jsonc.stringify({ error = err or "Incomplete input" }))
 | 
						|
		os.exit(1)
 | 
						|
	end
 | 
						|
 | 
						|
	return parse:get()
 | 
						|
end
 | 
						|
 | 
						|
local function validateArgs(func, uargs)
 | 
						|
	local method = methods[func]
 | 
						|
	if not method then
 | 
						|
		print(jsonc.stringify({ error = "Method not found" }))
 | 
						|
		os.exit(1)
 | 
						|
	end
 | 
						|
 | 
						|
	if type(uargs) ~= "table" then
 | 
						|
		print(jsonc.stringify({ error = "Invalid arguments" }))
 | 
						|
		os.exit(1)
 | 
						|
	end
 | 
						|
 | 
						|
	uargs.ubus_rpc_session = nil
 | 
						|
 | 
						|
	local k, v
 | 
						|
	local margs = method.args or {}
 | 
						|
	for k, v in pairs(uargs) do
 | 
						|
		if margs[k] == nil or
 | 
						|
		    (v ~= nil and type(v) ~= type(margs[k]))
 | 
						|
		then
 | 
						|
			print(jsonc.stringify({ error = "Invalid arguments" }))
 | 
						|
			os.exit(1)
 | 
						|
		end
 | 
						|
	end
 | 
						|
	return method
 | 
						|
end
 | 
						|
 | 
						|
if arg[1] == "list" then
 | 
						|
	local _, method, rv = nil, nil, {}
 | 
						|
	for _, method in pairs(methods) do rv[_] = method.args or {} end
 | 
						|
	print((jsonc.stringify(rv):gsub(":%[%]", ":{}")))
 | 
						|
elseif arg[1] == "call" then
 | 
						|
	local args = parseInput()
 | 
						|
	local method = validateArgs(arg[2], args)
 | 
						|
	local result, code = method.call(args)
 | 
						|
	print((jsonc.stringify(result):gsub("^%[%]$", "{}")))
 | 
						|
	os.exit(code or 0)
 | 
						|
end |