OpenWrt_Luci_Lua/1_1.mi_Lua/xiaoqiang/util/XQLanWanUtil.lua
2015-06-28 14:39:56 +08:00

962 lines
28 KiB
Lua

module ("xiaoqiang.util.XQLanWanUtil", package.seeall)
local XQFunction = require("xiaoqiang.common.XQFunction")
local XQConfigs = require("xiaoqiang.common.XQConfigs")
function getDefaultMacAddress()
local LuciUtil = require("luci.util")
local mac = LuciUtil.exec(XQConfigs.GET_DEFAULT_MACADDRESS)
if XQFunction.isStrNil(mac) then
mac = nil
else
mac = LuciUtil.trim(mac):match("(%S-),")
end
return string.upper(mac)
end
function getLanLinkList()
local LuciUtil = require("luci.util")
local lanLink = {}
local cmd = "et robord 0x01 0x00"
for _, line in ipairs(LuciUtil.execl(cmd)) do
local port,link = line:match('port (%d):(%S+)')
if link then
if tonumber(port) == 0 then
lanLink[1] = link == 'up' and 1 or 0
end
if tonumber(port) == 2 then
lanLink[2] = link == 'up' and 1 or 0
end
end
end
return lanLink
end
function getLanIp()
local uci = require("luci.model.uci").cursor()
local lan = uci:get_all("network", "lan")
return lan.ipaddr
end
--[[
@return WANLINKSTAT=UP/DOWN
@return LOCALDNSSTAT=UP/DOWN
@return VPNLINKSTAT=UP/DOWN
]]--
function getWanMonitorStat()
local NixioFs = require("nixio.fs")
local content = NixioFs.readfile(XQConfigs.WAN_MONITOR_STAT_FILEPATH)
local status = {}
if content ~= nil then
for line in string.gmatch(content, "[^\n]+") do
key,value = line:match('(%S+)=(%S+)')
status[key] = value
end
end
return status
end
function getAutoWanType()
local LuciUtil = require("luci.util")
local result = LuciUtil.execi("/usr/sbin/wanlinkprobe 1 WAN pppoe dhcp")
local link,pppoe,dhcp
if result then
for line in result do
if line:match("^LINK=(%S+)") ~= nil then
link = line:match("^LINK=(%S+)")
elseif line:match("^PPPOE=(%S+)") ~= nil then
pppoe = line:match("^PPPOE=(%S+)")
elseif line:match("^DHCP=(%S+)") ~= nil then
dhcp = line:match("^DHCP=(%S+)")
end
end
end
if pppoe == "YES" then
return 1
elseif dhcp == "YES" then
return 2
elseif link ~= "YES" then
return 99
else
return 0
end
end
function ubusWanStatus()
local ubus = require("ubus").connect()
local wan = ubus:call("network.interface.wan", "status", {})
local result = {}
if wan["ipv4-address"] and #wan["ipv4-address"] > 0 then
result["ipv4"] = wan["ipv4-address"][1]
else
result["ipv4"] = {
["mask"] = 0,
["address"] = ""
}
end
result["dns"] = wan["dns-server"] or {}
result["proto"] = string.lower(wan.proto or "dhcp")
result["up"] = wan.up
result["uptime"] = wan.uptime or 0
result["pending"] = wan.pending
result["autostart"] = wan.autostart
return result
end
function _pppoeStatusCheck()
local LuciJson = require("json")
local LuciUtil = require("luci.util")
local cmd = "lua /usr/sbin/pppoe.lua status"
local status = LuciUtil.exec(cmd)
if status then
status = LuciUtil.trim(status)
if XQFunction.isStrNil(status) then
return false
end
status = LuciJson.decode(status)
return status
else
return false
end
end
--- type
--- 1:认证失败(用户密码异常导致)
--- 2:无法连接服务器
--- 3:其他异常(协议不匹配等)
function _pppoeErrorCodeHelper(code)
local errorA = {
["507"] = 1,["691"] = 1,["509"] = 1,["514"] = 1,["520"] = 1,
["646"] = 1,["647"] = 1,["648"] = 1,["649"] = 1,["691"] = 1,
["646"] = 1
}
local errorB = {
["516"] = 1,["650"] = 1,["601"] = 1,["510"] = 1,["530"] = 1,
["531"] = 1
}
local errorC = {
["501"] = 1,["502"] = 1,["503"] = 1,["504"] = 1,["505"] = 1,
["506"] = 1,["507"] = 1,["508"] = 1,["511"] = 1,["512"] = 1,
["515"] = 1,["517"] = 1,["518"] = 1,["519"] = 1
}
local errcode = tostring(code)
if errcode then
if errorA[errcode] then
return 1
end
if errorB[errcode] then
return 2
end
if errorC[errcode] then
return 3
end
return 1
end
end
--- status
--- 0:未拨号
--- 1:正在拨号
--- 2:拨号成功
--- 3:正在拨号 但返现拨号错误信息
--- 4:关闭拨号
function getPPPoEStatus()
local result = {}
local status = ubusWanStatus()
if status then
local LuciNetwork = require("luci.model.network").init()
local network = LuciNetwork:get_network("wan")
if status.proto == "pppoe" then
if status.up then
result["status"] = 2
else
local check = _pppoeStatusCheck()
if check then
if check.process == "down" then
result["status"] = 4
elseif check.process == "up" then
result["status"] = 2
elseif check.process == "connecting" then
if check.code == nil or check.code == 0 then
result["status"] = 1
else
result["status"] = 3
result["errcode"] = check.msg or ""
result["errtype"] = _pppoeErrorCodeHelper(tostring(check.code))
end
end
else
result["status"] = 0
end
end
local configdns = network:get_option_value("dns")
if not XQFunction.isStrNil(configdns) then
result["cdns"] = luci.util.split(configdns," ")
end
result["pppoename"] = network:get_option_value("username")
result["password"] = network:get_option_value("password")
result["peerdns"] = network:get_option_value("peerdns")
else
result["status"] = 0
end
local device = network:get_interface()
local ipaddress = device:ipaddrs()
local ipv4 = {
["address"] = "",
["mask"] = ""
}
if ipaddress and #ipaddress > 0 then
ipv4["address"] = ipaddress[1]:host():string()
ipv4["mask"] = ipaddress[1]:mask():string()
end
result["ip"] = ipv4
result["dns"] = status.dns
result["proto"] = status.proto
result["gw"] = network:gwaddr() or ""
return result
else
return false
end
end
function pppoeStop()
os.execute("lua /usr/sbin/pppoe.lua down")
end
function pppoeStart()
XQFunction.forkExec("lua /usr/sbin/pppoe.lua up")
end
--[[
@param interface : lan/wan
]]--
function getLanWanInfo(interface)
if interface ~= "lan" and interface ~= "wan" then
return false
end
local LuciUtil = require("luci.util")
local LuciNetwork = require("luci.model.network").init()
local info = {}
local ipv6Dict = getIPv6Addrs()
local network = LuciNetwork:get_network(interface)
if network then
local device = network:get_interface()
local ipAddrs = device:ipaddrs()
local ip6Addrs = device:ip6addrs()
if interface == "wan" then
local mtuvalue = network:get_option_value("mtu")
if XQFunction.isStrNil(mtuvalue) then
mtuvalue = "1480"
end
info["mtu"] = tostring(mtuvalue)
info["details"] = getWanDetails()
-- 是否插了网线
local cmd = 'et robord 0x01 0x00'
local data = LuciUtil.exec(cmd)
if not XQFunction.isStrNil(data) then
local linkStat = string.match(data, 'port 4:([^%s]+)')
info["link"] = linkStat == 'up' and 1 or 0;
end
end
if device and #ipAddrs > 0 then
local ipAddress = {}
for _,ip in ipairs(ipAddrs) do
ipAddress[#ipAddress+1] = {}
ipAddress[#ipAddress]["ip"] = ip:host():string()
ipAddress[#ipAddress]["mask"] = ip:mask():string()
end
info["ipv4"] = ipAddress
end
if device and #ip6Addrs > 0 then
local ipAddress = {}
for _,ip in ipairs(ip6Addrs) do
ipAddress[#ipAddress+1] = {}
ipAddress[#ipAddress]["ip"] = ip:host():string()
ipAddress[#ipAddress]["mask"] = ip:mask():string()
if ipv6Dict[ip] then
ipAddress[#ipAddress]["type"] = ipv6Dict[ip].type
end
end
info["ipv6"] = ipAddress
end
info["gateWay"] = network:gwaddr()
if network:dnsaddrs() then
info["dnsAddrs"] = network:dnsaddrs()[1] or ""
info["dnsAddrs1"] = network:dnsaddrs()[2] or ""
else
info["dnsAddrs"] = ""
info["dnsAddrs1"] = ""
end
if device and device:mac() ~= "00:00:00:00:00:00" then
info["mac"] = device:mac()
end
if info["mac"] == nil then
info["mac"] = getWanMac()
end
if network:uptime() > 0 then
info["uptime"] = network:uptime()
else
info["uptime"] = 0
end
local status = network:status()
if status=="down" then
info["status"] = 0
elseif status=="up" then
info["status"] = 1
if info.details and info.details.wanType == "pppoe" then
wanMonitor = getWanMonitorStat()
if wanMonitor.WANLINKSTAT ~= "UP" then
info["status"] = 0
end
end
elseif status=="connection" then
info["status"] = 2
end
else
info = false
end
return info
end
function getWanEth()
local LuciNetwork = require("luci.model.network").init()
local wanNetwork = LuciNetwork:get_network("wan")
return wanNetwork:get_option_value("ifname")
end
function getWanMac()
local LuciUtil = require("luci.util")
local ifconfig = LuciUtil.exec("ifconfig " .. getWanEth())
if not XQFunction.isStrNil(ifconfig) then
return ifconfig:match('HWaddr (%S+)') or ""
else
return nil
end
end
--[[
@param interface : lan/wan
]]--
function getLanWanIp(interface)
if interface ~= "lan" and interface ~= "wan" then
return false
end
local LuciNetwork = require("luci.model.network").init()
local ipv4 = {}
local network = LuciNetwork:get_network(interface)
if network then
local device = network:get_interface()
local ipAddrs = device:ipaddrs()
if device and #ipAddrs > 0 then
for _,ip in ipairs(ipAddrs) do
ipv4[#ipv4+1] = {}
ipv4[#ipv4]["ip"] = ip:host():string()
ipv4[#ipv4]["mask"] = ip:mask():string()
end
end
end
return ipv4
end
function checkLanIp(ip)
local LuciIp = require("luci.ip")
local ipNl = LuciIp.iptonl(ip)
if (ipNl >= LuciIp.iptonl("10.0.0.0") and ipNl <= LuciIp.iptonl("10.255.255.255"))
or (ipNl >= LuciIp.iptonl("172.16.0.0") and ipNl <= LuciIp.iptonl("172.31.255.255"))
or (ipNl >= LuciIp.iptonl("192.168.0.0") and ipNl <= LuciIp.iptonl("192.168.255.255")) then
return 0
else
return 1527
end
end
function setLanIp(ip,mask)
local XQEvent = require("xiaoqiang.XQEvent")
local LuciNetwork = require("luci.model.network").init()
local network = LuciNetwork:get_network("lan")
network:set("ipaddr",ip)
network:set("netmask",mask)
LuciNetwork:commit("network")
LuciNetwork:save("network")
XQEvent.lanIPChange(ip)
return true
end
function getIPv6Addrs()
local LuciIp = require("luci.ip")
local LuciUtil = require("luci.util")
local cmd = "ifconfig|grep inet6"
local ipv6List = LuciUtil.execi(cmd)
local result = {}
for line in ipv6List do
line = luci.util.trim(line)
local ipv6,mask,ipType = line:match('inet6 addr: ([^%s]+)/([^%s]+)%s+Scope:([^%s]+)')
if ipv6 then
ipv6 = LuciIp.IPv6(ipv6,"ffff:ffff:ffff:ffff::")
ipv6 = ipv6:host():string()
result[ipv6] = {}
result[ipv6]['ip'] = ipv6
result[ipv6]['mask'] = mask
result[ipv6]['type'] = ipType
end
end
return result
end
function getLanDHCPService()
local LuciUci = require "luci.model.uci"
local lanDhcpStatus = {}
local uciCursor = LuciUci.cursor()
local ignore = uciCursor:get("dhcp", "lan", "ignore")
local leasetime = uciCursor:get("dhcp", "lan", "leasetime")
if ignore ~= "1" then
ignore = "0"
end
local leasetimeNum,leasetimeUnit = leasetime:match("^(%d+)([^%d]+)")
lanDhcpStatus["lanIp"] = getLanWanIp("lan")
lanDhcpStatus["start"] = uciCursor:get("dhcp", "lan", "start")
lanDhcpStatus["limit"] = uciCursor:get("dhcp", "lan", "limit")
lanDhcpStatus["leasetime"] = leasetime
lanDhcpStatus["leasetimeNum"] = leasetimeNum
lanDhcpStatus["leasetimeUnit"] = leasetimeUnit
lanDhcpStatus["ignore"] = ignore
return lanDhcpStatus
end
--[[
Set Lan DHCP, range = start~end
]]--
function setLanDHCPService(startReq,endReq,leasetime,ignore)
local LuciUci = require("luci.model.uci")
local LuciUtil = require("luci.util")
local uciCursor = LuciUci.cursor()
if ignore == "1" then
uciCursor:set("dhcp", "lan", "ignore", tonumber(ignore))
else
local limit = tonumber(endReq) - tonumber(startReq) + 1
if limit < 0 then
return false
end
uciCursor:set("dhcp", "lan", "start", tonumber(startReq))
uciCursor:set("dhcp", "lan", "limit", tonumber(limit))
uciCursor:set("dhcp", "lan", "leasetime", leasetime)
uciCursor:delete("dhcp", "lan", "ignore")
end
uciCursor:save("dhcp")
uciCursor:load("dhcp")
uciCursor:commit("dhcp")
uciCursor:load("dhcp")
LuciUtil.exec("/etc/init.d/dnsmasq restart > /dev/null")
return true
end
function wanDown()
local LuciUtil = require("luci.util")
LuciUtil.exec("env -i /sbin/ifdown wan")
end
function wanRestart()
local LuciUtil = require("luci.util")
LuciUtil.exec("env -i /sbin/ifup wan")
XQFunction.forkExec("/etc/init.d/filetunnel restart")
end
function dnsmsqRestart()
local LuciUtil = require("luci.util")
LuciUtil.exec("ubus call network reload; sleep 1; /etc/init.d/dnsmasq restart > /dev/null")
end
--[[
Get wan details, static ip/pppoe/dhcp/mobile
@return {proto="dhcp",ifname=ifname,dns=dns,peerdns=peerdns}
@return {proto="static",ifname=ifname,ipaddr=ipaddr,netmask=netmask,gateway=gateway,dns=dns}
@return {proto="pppoe",ifname=ifname,username=pppoename,password=pppoepasswd,dns=dns,peerdns=peerdns}
]]--
function getWanDetails()
local LuciNetwork = require("luci.model.network").init()
local wanNetwork = LuciNetwork:get_network("wan")
local wanDetails = {}
if wanNetwork then
local wanType = wanNetwork:proto()
if wanType == "mobile" or wanType == "3g" then
wanType = "mobile"
elseif wanType == "static" then
wanDetails["ipaddr"] = wanNetwork:get_option_value("ipaddr")
wanDetails["netmask"] = wanNetwork:get_option_value("netmask")
wanDetails["gateway"] = wanNetwork:get_option_value("gateway")
elseif wanType == "pppoe" then
wanDetails["username"] = wanNetwork:get_option_value("username")
wanDetails["password"] = wanNetwork:get_option_value("password")
wanDetails["peerdns"] = wanNetwork:get_option_value("peerdns")
wanDetails["service"] = wanNetwork:get_option_value("service")
elseif wanType == "dhcp" then
wanDetails["peerdns"] = wanNetwork:get_option_value("peerdns")
end
if not XQFunction.isStrNil(wanNetwork:get_option_value("dns")) then
wanDetails["dns"] = luci.util.split(wanNetwork:get_option_value("dns")," ")
end
wanDetails["wanType"] = wanType
wanDetails["ifname"] = wanNetwork:get_option_value("ifname")
return wanDetails
else
return nil
end
end
function generateDns(dns1, dns2, peerdns)
local dns
if not XQFunction.isStrNil(dns1) and not XQFunction.isStrNil(dns2) then
dns = {dns1,dns2}
elseif not XQFunction.isStrNil(dns1) then
dns = dns1
elseif not XQFunction.isStrNil(dns2) then
dns = dns2
end
return dns
end
function checkMTU(value)
local mtu = tonumber(value)
if mtu and mtu >= 576 and mtu <= 1498 then
return true
else
return false
end
end
function setWanPPPoE(name, password, dns1, dns2, peerdns, mtu, service)
local XQPreference = require("xiaoqiang.XQPreference")
local LuciNetwork = require("luci.model.network").init()
local uci = require("luci.model.uci").cursor()
local macaddr = uci:get("network", "wan", "macaddr")
local iface = "wan"
local ifname = getWanEth()
local oldconf = uci:get_all("network", "wan") or {}
local wanrestart = true
local dnsrestart = true
if oldconf.username == name
and oldconf.password == password
and tonumber(oldconf.mtu) == tonumber(mtu)
and ((XQFunction.isStrNil(oldconf.service) and XQFunction.isStrNil(service)) or oldconf.service == service) then
wanrestart = false
end
local dnss = {}
local odnss = {}
if oldconf.dns and type(oldconf.dns) == "string" then
odnss = {oldconf.dns}
elseif oldconf.dns and type(oldconf.dns) == "table" then
odnss = oldconf.dns
end
if not XQFunction.isStrNil(dns1) then
table.insert(dnss, dns1)
end
if not XQFunction.isStrNil(dns2) then
table.insert(dnss, dns2)
end
if #dnss == #odnss then
if #dnss == 0 then
dnsrestart = false
else
local odnsd = {}
local match = 0
for _, dns in ipairs(odnss) do
odnsd[dns] = 1
end
for _, dns in ipairs(dnss) do
if odnsd[dns] == 1 then
match = match + 1
end
end
if match == #dnss then
dnsrestart = false
end
end
end
local wanNet = LuciNetwork:del_network(iface)
local mtuvalue
if mtu then
if checkMTU(mtu) then
mtuvalue = tonumber(mtu)
else
return false
end
else
mtuvalue = 1480
end
wanNet = LuciNetwork:add_network(
iface, {
proto ="pppoe",
ifname = ifname,
username = name,
password = password,
dns = generateDns(dns1,dns2,peerdns),
peerdns = peerdns,
macaddr = macaddr,
service = service,
mtu = mtuvalue
})
if not XQFunction.isStrNil(name) then
XQPreference.set(XQConfigs.PREF_PPPOE_NAME,name)
XQFunction.nvramSet("nv_pppoe_name", name)
end
if not XQFunction.isStrNil(password) then
XQPreference.set(XQConfigs.PREF_PPPOE_PASSWORD,password)
XQFunction.nvramSet("nv_pppoe_pwd", password)
end
XQFunction.nvramSet("nv_wan_type", "pppoe")
XQFunction.nvramCommit()
if wanNet then
LuciNetwork:save("network")
LuciNetwork:commit("network")
os.execute(XQConfigs.VPN_DISABLE)
if dnsrestart then
dnsmsqRestart()
end
if wanrestart then
wanRestart()
else
local pppoestatus = getPPPoEStatus()
if pppoestatus and pppoestatus.status == 4 then
pppoeStart()
end
end
return true
else
return false
end
end
function checkWanIp(ip)
local LuciIp = require("luci.ip")
local ipNl = LuciIp.iptonl(ip)
if (ipNl >= LuciIp.iptonl("1.0.0.0") and ipNl <= LuciIp.iptonl("126.0.0.0"))
or (ipNl >= LuciIp.iptonl("128.0.0.0") and ipNl <= LuciIp.iptonl("223.255.255.255")) then
return 0
else
return 1533
end
end
function setWanStaticOrDHCP(ipType, ip, mask, gw, dns1, dns2, peerdns, mtu)
local LuciNetwork = require("luci.model.network").init()
local uci = require("luci.model.uci").cursor()
local macaddr = uci:get("network", "wan", "macaddr")
local oldconf = uci:get_all("network", "wan") or {}
local iface = "wan"
local ifname = getWanEth()
local dnsrestart = true
local wanrestart = true
local dnss = {}
local odnss = {}
if oldconf.dns and type(oldconf.dns) == "string" then
odnss = {oldconf.dns}
elseif oldconf.dns and type(oldconf.dns) == "table" then
odnss = oldconf.dns
end
if not XQFunction.isStrNil(dns1) then
table.insert(dnss, dns1)
end
if not XQFunction.isStrNil(dns2) then
table.insert(dnss, dns2)
end
if #dnss == #odnss then
if #dnss == 0 then
dnsrestart = false
else
local odnsd = {}
local match = 0
for _, dns in ipairs(odnss) do
odnsd[dns] = 1
end
for _, dns in ipairs(dnss) do
if odnsd[dns] == 1 then
match = match + 1
end
end
if match == #dnss then
dnsrestart = false
end
end
end
local wanNet = LuciNetwork:del_network(iface)
local dns = generateDns(dns1, dns2, peerdns)
local mtuvalue
if mtu then
mtuvalue = tonumber(mtu)
end
if ipType == "dhcp" then
if oldconf.proto == "dhcp" then
wanrestart = false
end
local network = {
proto = "dhcp",
ifname = ifname,
dns = dns,
macaddr = macaddr,
peerdns = peerdns
}
if mtu then
network["mtu"] = mtuvalue
end
wanNet = LuciNetwork:add_network(iface, network)
elseif ipType == "static" then
if oldconf.proto == "static"
and oldconf.ipaddr == ip
and oldconf.netmask == mask
and oldconf.gateway == gw
and oldconf.mtu == mtuvalue then
wanrestart = false
end
if not dns then
dns = gw
end
local network = {
proto = "static",
ipaddr = ip,
netmask = mask,
gateway = gw,
dns = dns,
macaddr = macaddr,
ifname = ifname
}
if mtu then
network["mtu"] = mtuvalue
end
wanNet = LuciNetwork:add_network(iface, network)
end
XQFunction.nvramSet("nv_wan_type", ipType)
XQFunction.nvramCommit()
if wanNet then
LuciNetwork:save("network")
LuciNetwork:commit("network")
if dnsrestart then
dnsmsqRestart()
end
if wanrestart then
wanRestart()
end
return true
else
return false
end
end
function setWanMac(mac)
local LuciNetwork = require("luci.model.network").init()
local LuciDatatypes = require("luci.cbi.datatypes")
local network = LuciNetwork:get_network("wan")
local oldMac = network:get_option_value("macaddr")
local succeed = false
if oldMac ~= mac then
if XQFunction.isStrNil(mac) then
local defaultMac = getDefaultMacAddress() or ""
network:set("macaddr",defaultMac)
succeed = true
elseif LuciDatatypes.macaddr(mac) and mac ~= "ff:ff:ff:ff:ff:ff" and mac ~= "00:00:00:00:00:00" then
network:set("macaddr",mac)
succeed = true
end
else
succeed = true
end
if succeed then
LuciNetwork:save("network")
LuciNetwork:commit("network")
wanRestart()
end
return succeed
end
function _checkIP(ip)
if XQFunction.isStrNil(ip) then
return false
end
local LuciIp = require("luci.ip")
local ipNl = LuciIp.iptonl(ip)
if (ipNl >= LuciIp.iptonl("1.0.0.0") and ipNl <= LuciIp.iptonl("126.0.0.0"))
or (ipNl >= LuciIp.iptonl("128.0.0.0") and ipNl <= LuciIp.iptonl("223.255.255.255")) then
return true
else
return false
end
end
function _checkMac(mac)
if XQFunction.isStrNil(mac) then
return false
end
local LuciDatatypes = require("luci.cbi.datatypes")
if LuciDatatypes.macaddr(mac) and mac ~= "ff:ff:ff:ff:ff:ff" and mac ~= "00:00:00:00:00:00" then
return true
else
return false
end
end
function _parseMac(mac)
if mac then
return string.lower(string.gsub(mac,"[:-]",""))
else
return nil
end
end
function _parseDhcpLeases()
local NixioFs = require("nixio.fs")
local uci = require("luci.model.uci").cursor()
local result = {}
local leasefile = XQConfigs.DHCP_LEASE_FILEPATH
uci:foreach("dhcp", "dnsmasq",
function(s)
if s.leasefile and NixioFs.access(s.leasefile) then
leasefile = s.leasefile
return false
end
end)
local dhcp = io.open(leasefile, "r")
if dhcp then
for line in dhcp:lines() do
if line then
local ts, mac, ip, name = line:match("^(%d+) (%S+) (%S+) (%S+)")
if name == "*" then
name = ""
end
if ts and mac and ip and name then
result[ip] = {
mac = string.lower(XQFunction.macFormat(mac)),
ip = ip,
name = name
}
end
end
end
dhcp:close()
end
return result
end
--
-- Event
--
function hookLanIPChangeEvent(ip)
if XQFunction.isStrNil(ip) then
return
end
local uci = require("luci.model.uci").cursor()
local lan = ip:gsub(".%d+$","")
uci:foreach("macbind", "host",
function(s)
local ip = s.ip
ip = lan.."."..ip:match(".(%d+)$")
uci:set("macbind", s[".name"], "ip", ip)
end
)
uci:foreach("dhcp", "host",
function(s)
local ip = s.ip
ip = lan.."."..ip:match(".(%d+)$")
uci:set("dhcp", s[".name"], "ip", ip)
end
)
uci:commit("dhcp")
uci:commit("macbind")
end
--- Tag
--- 0:未添加
--- 1:已添加
--- 2:已绑定
function macBindInfo()
local uci = require("luci.model.uci").cursor()
local info = {}
uci:foreach("macbind", "host",
function(s)
local item = {
["name"] = s.name,
["mac"] = s.mac,
["ip"] = s.ip,
["tag"] = 1
}
info[s.mac] = item
end
)
uci:foreach("dhcp", "host",
function(s)
local item = {
["name"] = s.name,
["mac"] = s.mac,
["ip"] = s.ip,
["tag"] = 2
}
info[s.mac] = item
end
)
return info
end
--- 0:设置成功
--- 1:IP冲突
--- 2:MAC/IP 不合法
function addBind(mac, ip)
local uci = require("luci.model.uci").cursor()
if _checkIP(ip) and _checkMac(mac) then
local dhcp = _parseDhcpLeases()
mac = string.lower(XQFunction.macFormat(mac))
local host = dhcp[ip]
if host and host.mac ~= mac then
return 1
end
local name = _parseMac(mac)
local options = {
["name"] = name,
["mac"] = mac,
["ip"] = ip
}
uci:section("macbind", "host", name, options)
uci:commit("macbind")
else
return 2
end
return 0
end
function removeBind(mac)
local uci = require("luci.model.uci").cursor()
if _checkMac(mac) then
local name = _parseMac(mac)
uci:delete("macbind", name)
uci:delete("dhcp", name)
uci:commit("macbind")
uci:commit("dhcp")
return true
else
return false
end
end
function unbindAll()
local uci = require("luci.model.uci").cursor()
uci:delete_all("dhcp", "host")
uci:delete_all("macbind", "host")
uci:commit("dhcp")
uci:commit("macbind")
end
function saveBindInfo()
local uci = require("luci.model.uci").cursor()
uci:delete_all("dhcp", "host")
uci:foreach("macbind", "host",
function(s)
local options = {
["name"] = s.name,
["mac"] = s.mac,
["ip"] = s.ip
}
uci:section("dhcp", "host", s.name, options)
end
)
uci:commit("dhcp")
end