OpenWrt_Luci_Lua/Mi_Lua/xiaoqiang/module/XQPortForward.lua

266 lines
7.3 KiB
Lua
Raw Normal View History

2015-05-09 10:48:46 +00:00
module ("xiaoqiang.module.XQPortForward", package.seeall)
local XQFunction = require("xiaoqiang.common.XQFunction")
local XQConfigs = require("xiaoqiang.common.XQConfigs")
--
-- 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("firewall", "redirect",
function(s)
local ftype = tonumber(s.ftype)
if ftype then
local destip = s.dest_ip
destip = lan.."."..destip:match(".(%d+)$")
uci:set("firewall", s[".name"], "dest_ip", destip)
end
end
)
uci:commit("firewall")
end
-- proto
-- 1: tcp
-- 2: udp
-- 3: tcp and udp
-- default: 1/tcp
function _protoHelper(proto)
if proto and type(proto) == "number" then
if proto == 1 then
return "tcp"
elseif proto == 2 then
return "udp"
elseif proto == 3 then
return "tcpudp"
else
return "tcp"
end
end
if proto and type("proto") == "string" then
if proto == "tcp" then
return 1
elseif proto == "udp" then
return 2
elseif proto == "tcpudp" then
return 3
else
return 1
end
end
return nil
end
function _portCheck(port)
if port and type(port) == "number" and port > 0 then
return true
else
return false
end
end
function _portRangeOverlap(port1, port2)
local LuciUtil = require("luci.util")
if port1 and port2 then
port1 = tostring(port1)
port2 = tostring(port2)
if port1 == port2 then
return false
end
local range1 = {}
local range2 = {}
if port1:match("-") then
local sp = LuciUtil.split(port1, "-")
range1["f"] = tonumber(sp[1])
range1["t"] = tonumber(sp[2])
else
range1["f"] = tonumber(port1)
range1["t"] = tonumber(port1)
end
if port2:match("-") then
local sp = LuciUtil.split(port2, "-")
range2["f"] = tonumber(sp[1])
range2["t"] = tonumber(sp[2])
else
range2["f"] = tonumber(port2)
range2["t"] = tonumber(port2)
end
if (range1.f >= range2.f and range1.f <= range2.t) or
(range1.t >= range2.f and range1.t <= range2.t) then
return true
end
end
return false
end
function _portConflictCheck(port)
local uci = require("luci.model.uci").cursor()
local result = false
uci:foreach("firewall", "redirect",
function(s)
if _portRangeOverlap(port, s.src_dport) then
result = true
end
end
)
return result
end
function moduleOn()
return #portForwards(0) > 0
end
-- status
-- 0:关闭
-- 1:开启
-- 2:冲突(DMZ功能开启NAT功能就不能开启)
function portForwardInfo()
local XQDMZModule = require("xiaoqiang.module.XQDMZModule")
local info = {}
if XQDMZModule.moduleOn() then
info["status"] = 2
else
info["status"] = moduleOn() and 1 or 0
end
return info
end
-- ftype
-- 0: all
-- 1: port
-- 2: range
function portForwards(ftype)
local uci = require("luci.model.uci").cursor()
local portforwards = {}
local forwardtype = tonumber(ftype) or 0
uci:foreach("firewall", "redirect",
function(s)
local ftype = tonumber(s.ftype)
if ftype and forwardtype == 0 or forwardtype == ftype then
local item = {}
item.name = s.name
item.destip = s.dest_ip
item.proto = _protoHelper(s.proto) or 1
if ftype == 1 then
item.srcport = tonumber(s.src_dport)
item.destport = s.dest_port
item.ftype = 1
elseif ftype == 2 then
item.ftype = 2
local portrange = {}
local LuciUtil = require("luci.util")
local sp = LuciUtil.split(s.src_dport, "-")
item.srcport = {
["f"] = tonumber(sp[1]),
["t"] = tonumber(sp[2])
}
end
table.insert(portforwards, item)
end
end
)
return portforwards
end
-- return
-- 0: 设置成功
-- 1: 参数不合法
-- 2: 端口冲突(设置的端口和已有端口有重叠)
-- 3: 功能冲突由于DMZ开启
function setPortForward(name, ip, sport, dport, proto)
if not XQFunction.isStrNil(ip) and _portCheck(tonumber(sport)) and _portCheck(tonumber(dport)) then
local uci = require("luci.model.uci").cursor()
if portForwardInfo().status == 2 then
return 3
end
if _portConflictCheck(sport) then
return 2
end
local sname = string.format("wan%srdr", tostring(sport))
local options = {
["src"] = "wan",
["src_dport"] = sport,
["proto"] = _protoHelper(tonumber(proto)) or "tcp",
["target"] = "DNAT",
["dest"] = "lan",
["dest_port"] = dport,
["dest_ip"] = ip,
["ftype"] = 1,
["name"] = name or ""
}
uci:section("firewall", "redirect", sname, options)
uci:commit("firewall")
return 0
end
return 1
end
-- return
-- 0: 设置成功
-- 1: 参数不合法
-- 2: 端口冲突(设置的端口和已有端口有重叠)
function setRangePortForward(name, ip, fport, tport, proto)
if not XQFunction.isStrNil(ip) and _portCheck(tonumber(fport)) and _portCheck(tonumber(tport)) then
if tonumber(fport) > tonumber(tport) then
return 1
end
local uci = require("luci.model.uci").cursor()
local sport = tostring(fport).."-"..tostring(tport)
if portForwardInfo().status == 2 then
return 3
end
if _portConflictCheck(sport) then
return 2
end
local sname = string.format("wan%srdr", tostring(fport))
local options = {
["src"] = "wan",
["src_dport"] = sport,
["proto"] = _protoHelper(tonumber(proto)) or "tcp",
["target"] = "DNAT",
["dest"] = "lan",
["dest_ip"] = ip,
["ftype"] = 2,
["name"] = name or ""
}
uci:section("firewall", "redirect", sname, options)
uci:commit("firewall")
return 0
end
return 1
end
function deletePortForward(port)
if _portCheck(tonumber(port)) then
local uci = require("luci.model.uci").cursor()
local sname = string.format("wan%srdr", tostring(port))
uci:delete("firewall", sname)
uci:commit("firewall")
return true
end
return false
end
function deleteAllPortForward()
local uci = require("luci.model.uci").cursor()
uci:delete_all("firewall", "redirect",
function(s)
if s.ftype then
return true
else
return false
end
end
)
uci:commit("firewall")
return true
end
function restart()
os.execute("/etc/init.d/firewall restart")
end