--[[ @object-name: edgerouter @object-desc: 旁路由模式 --]] local uci = require "uci" local lnet = require "oui.network" local hardware = require "hardware" local M = {} local function file_exists(path) local file = io.open(path, "rb") if file then file:close() end return file ~= nil end local function split_ip(ip) local fields={} for field in ip:gmatch("[^.]+") do fields[#fields + 1] = field end return fields end local function get_address_pool(gateway,mask) local ret = {} local net = lnet.ipcalc({gateway,mask}); local fileds=split_ip(net.network) local start=tonumber(fileds[4]) local ending=tonumber(split_ip(net.broadcast)[4]) local gw=tonumber(split_ip(gateway)[4]) for i=start+1,ending-1,1 do if i ~= gw then ret["start"]= tostring(i) -- ret["start"]= fileds[1] .. "." .. fileds[2] .. "." .. fileds[3] .. "." .. tostring(i) break end end for i=ending-1,start+1,-1 do if i ~= gw then ret["end"]= tostring(i) -- ret["end"]= fileds[1] .. "." .. fileds[2] .. "." .. fileds[3] .. "." .. tostring(i) break end end return ret end local function check_config_valid(info) local c = uci.cursor() local ip = c:get("edgerouter", "wandhcp", "ip") or "0.0.0.0" local mask = c:get("edgerouter", "wandhcp", "netmask") or "0.0.0.0" local cfg_net = lnet.ipcalc({ip,mask}); local info_net = lnet.ipcalc({info.ip,info.netmask}); if cfg_net.network == info_net.network then return true else return false end end --[[ @method-type: call @method-name: get_status @method-desc: 获取局域网中的设备流量通过旁路由的状态 @out number detected 上级DHCP服务器状态;(0:上级DHCP服务器已关闭,1:上级DHCP服务器开启并且已经将网关指向旁路由,2:上级服务器开启,3:物理网线未连接) @out string ?ip DHCP服务器分配的IP;如果detected字段为2,则该字段有效 @out string ?netmask DHCP服务器掩码;如果detected字段为2,则该字段有效 @out string ?gateway DHCP服务器地址;如果detected字段为非0值,则该字段有效 @out array ?dns DHCP服务器DNS;如果detected字段为2,则该字段有效 @out bool ?valid 当前配置是否有效;如果detected字段为2,则该字段有效 @out number ?err_code 错误码 @out string ?err_msg 错误信息 @in-example: {"jsonrpc":"2.0","id":1,"method":"call","params":["","edgerouter","get_status",{}]} @out-example: {"jsonrpc": "2.0", "id": 1, "result": {"detected":false}} --]] function M.get_status() local ret = {} local s = hardware.platform_get_wan_status() if s.cable_enabled == false then ret["detected"]=3 return ret end os.execute(". /lib/functions/drop-in-function.sh;check_dhcp_server") if file_exists("/tmp/drop-in-dhcp-info") then ret["detected"]=2 local dns = {} local c = uci.cursor() local our_ip = c:get("edgerouter", "wandhcp", "ip") for line in io.lines("/tmp/drop-in-dhcp-info") do local fields = {} for field in line:gmatch("%S+") do fields[#fields + 1] = field end if fields[1] == "router:" then if our_ip ~= nil and fields[2] == our_ip then ret["detected"]=1 end end if fields[1] == "yiaddr:" then ret["ip"] = fields[2] end if fields[1] == "giaddr:" then ret["gateway"] = fields[2] -- 使用网关地址作为首先DNS dns[1] = fields[2] end if fields[1] == "netmask:" then ret["netmask"] = fields[2] end -- DHCP 下发的DNS作为备选 if fields[1] == "dns1:" and fields[2] ~= "0.0.0.0" and fields[2] ~= dns[1] then dns[2] = fields[2] end end if #dns then ret["dns"] = dns end ret["valid"] = check_config_valid(ret) else ret["detected"]=0 end return ret end --[[ @method-type: call @method-name: set_config @method-desc: 设置旁路由模式相关配置 @in bool enable 是否使能;false:不使能,true:使能 @in string ?ip ip地址,在enable参数为真时为必须参数 @in string ?netmask 子网掩码,在enable参数为真时为必须参数 @in string ?gateway 网关地址,在enable参数为真时为必须参数 @in array ?dns DNS服务器地址,至少填写一个,在enable参数为真时为必须参数 @out number ?err_code 错误码 @out string ?err_msg 错误信息 @in-example: {"jsonrpc":"2.0","id":1,"method":"call","params":["","edgerouter","set_config",{"enable":true,"ip":"192.168.99.129","netmask":"255.255.255.0","gateway":"192.168.99.1","dns":["192.168.99.1","114.114.114.114"]}]} @out-example: {"jsonrpc": "2.0", "id": 1, "result": {}} --]] function M.set_config(params) if params.enable == nil then return { err_code = 1, err_msg = "parameter missing" } end if params.enable then if params.ip == nil or params.netmask == nil or params.gateway == nil or params.dns == nil then return { err_code = 1, err_msg = "parameter missing" } end end local c = uci.cursor() c:set("edgerouter", "global", "global") c:set("edgerouter", "global", "enabled", params.enable and "1" or "0") if params.enable then local pool=get_address_pool(params.gateway,params.netmask) c:set("edgerouter", "wandhcp", "dhcp") c:set("edgerouter", "wandhcp", "ip", params.ip) c:set("edgerouter", "wandhcp", "netmask", params.netmask) c:set("edgerouter", "wandhcp", "gateway", params.gateway) c:set("edgerouter", "wandhcp", "dns", params.dns) c:set("edgerouter", "wandhcp", "start", pool.start) c:set("edgerouter", "wandhcp", "end", pool["end"]) end c:commit("edgerouter") os.execute("/etc/init.d/edgerouter restart &") return {} end --[[ @method-type: call @method-name: get_config @method-desc: 获取旁路由相关配置 @out bool enable 是否使能;false:不使能,true:使能 @out string ip ip地址 @out string netmask 子网掩码 @out string gateway 网关地址 @out array dns DNS服务器地址,至少返回一个 @out number ?err_code 错误码 @out string ?err_msg 错误信息 @in-example: {"jsonrpc":"2.0","id":1,"method":"call","params":["","edgerouter","get_config",{}]} @out-example: {"jsonrpc": "2.0", "id": 1, "result": {"enable":true,"ip":"192.168.99.129","netmask":"255.255.255.0","gateway":"192.168.99.1","dns":["192.168.99.1","114.114.114.114"]}} --]] function M.get_config() local ret = {} local c = uci.cursor() local ip local netmask local gateway local dns local enable = c:get("edgerouter", "global", "enabled") or '0' ip = c:get("edgerouter", "wandhcp", "ip") netmask = c:get("edgerouter", "wandhcp", "netmask") gateway = c:get("edgerouter", "wandhcp", "gateway") dns = c:get("edgerouter", "wandhcp", "dns") ret["enable"] = enable ~= "0" ret["ip"] = ip ret["netmask"] = netmask ret["gateway"] = gateway ret["dns"] = dns return ret end return M