libs/sys: add ip6tables support to luci.sys.iptparser
This commit is contained in:
parent
825329ed41
commit
b477dae307
1 changed files with 38 additions and 16 deletions
|
@ -28,12 +28,25 @@ module("luci.sys.iptparser")
|
||||||
--- Create a new iptables parser object.
|
--- Create a new iptables parser object.
|
||||||
-- @class function
|
-- @class function
|
||||||
-- @name IptParser
|
-- @name IptParser
|
||||||
|
-- @param family Number specifying the address family. 4 for IPv4, 6 for IPv6
|
||||||
-- @return IptParser instance
|
-- @return IptParser instance
|
||||||
IptParser = luci.util.class()
|
IptParser = luci.util.class()
|
||||||
|
|
||||||
function IptParser.__init__( self, ... )
|
function IptParser.__init__( self, family )
|
||||||
|
self._family = (tonumber(family) == 6) and 6 or 4
|
||||||
self._rules = { }
|
self._rules = { }
|
||||||
self._chains = { }
|
self._chains = { }
|
||||||
|
|
||||||
|
if self._family == 4 then
|
||||||
|
self._nulladdr = "0.0.0.0/0"
|
||||||
|
self._tables = { "filter", "nat", "mangle", "raw" }
|
||||||
|
self._command = "iptables -t %s --line-numbers -nxvL"
|
||||||
|
else
|
||||||
|
self._nulladdr = "::/0"
|
||||||
|
self._tables = { "filter", "mangle", "raw" }
|
||||||
|
self._command = "ip6tables -t %s --line-numbers -nxvL"
|
||||||
|
end
|
||||||
|
|
||||||
self:_parse_rules()
|
self:_parse_rules()
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -49,9 +62,9 @@ end
|
||||||
-- <li> protocol - Match rules that match the given protocol, rules with
|
-- <li> protocol - Match rules that match the given protocol, rules with
|
||||||
-- protocol "all" are always matched
|
-- protocol "all" are always matched
|
||||||
-- <li> source - Match rules with the given source, rules with source
|
-- <li> source - Match rules with the given source, rules with source
|
||||||
-- "0.0.0.0/0" are always matched
|
-- "0.0.0.0/0" (::/0) are always matched
|
||||||
-- <li> destination - Match rules with the given destination, rules with
|
-- <li> destination - Match rules with the given destination, rules with
|
||||||
-- destination "0.0.0.0/0" are always matched
|
-- destination "0.0.0.0/0" (::/0) are always matched
|
||||||
-- <li> inputif - Match rules with the given input interface, rules
|
-- <li> inputif - Match rules with the given input interface, rules
|
||||||
-- with input interface "*" (=all) are always matched
|
-- with input interface "*" (=all) are always matched
|
||||||
-- <li> outputif - Match rules with the given output interface, rules
|
-- <li> outputif - Match rules with the given output interface, rules
|
||||||
|
@ -76,8 +89,8 @@ end
|
||||||
-- or "*" for all interfaces
|
-- or "*" for all interfaces
|
||||||
-- <li> outputif - Output interface of the rule,e.g. "eth0.0"
|
-- <li> outputif - Output interface of the rule,e.g. "eth0.0"
|
||||||
-- or "*" for all interfaces
|
-- or "*" for all interfaces
|
||||||
-- <li> source - The source ip range, e.g. "0.0.0.0/0"
|
-- <li> source - The source ip range, e.g. "0.0.0.0/0" (::/0)
|
||||||
-- <li> destination - The destination ip range, e.g. "0.0.0.0/0"
|
-- <li> destination - The destination ip range, e.g. "0.0.0.0/0" (::/0)
|
||||||
-- <li> options - A list of specific options of the rule,
|
-- <li> options - A list of specific options of the rule,
|
||||||
-- e.g. { "reject-with", "tcp-reset" }
|
-- e.g. { "reject-with", "tcp-reset" }
|
||||||
-- <li> packets - The number of packets matched by the rule
|
-- <li> packets - The number of packets matched by the rule
|
||||||
|
@ -102,8 +115,8 @@ function IptParser.find( self, args )
|
||||||
local args = args or { }
|
local args = args or { }
|
||||||
local rv = { }
|
local rv = { }
|
||||||
|
|
||||||
args.source = args.source and luci.ip.IPv4(args.source)
|
args.source = args.source and self:_parse_addr(args.source)
|
||||||
args.destination = args.destination and luci.ip.IPv4(args.destination)
|
args.destination = args.destination and self:_parse_addr(args.destination)
|
||||||
|
|
||||||
for i, rule in ipairs(self._rules) do
|
for i, rule in ipairs(self._rules) do
|
||||||
local match = true
|
local match = true
|
||||||
|
@ -137,16 +150,16 @@ function IptParser.find( self, args )
|
||||||
|
|
||||||
-- match source
|
-- match source
|
||||||
if not ( match == true and (
|
if not ( match == true and (
|
||||||
not args.source or rule.source == "0.0.0.0/0" or
|
not args.source or rule.source == self._nulladdr or
|
||||||
luci.ip.IPv4(rule.source):contains(args.source)
|
self:_parse_addr(rule.source):contains(args.source)
|
||||||
) ) then
|
) ) then
|
||||||
match = false
|
match = false
|
||||||
end
|
end
|
||||||
|
|
||||||
-- match destination
|
-- match destination
|
||||||
if not ( match == true and (
|
if not ( match == true and (
|
||||||
not args.destination or rule.destination == "0.0.0.0/0" or
|
not args.destination or rule.destination == self._nulladdr or
|
||||||
luci.ip.IPv4(rule.destination):contains(args.destination)
|
self:_parse_addr(rule.destination):contains(args.destination)
|
||||||
) ) then
|
) ) then
|
||||||
match = false
|
match = false
|
||||||
end
|
end
|
||||||
|
@ -241,26 +254,35 @@ function IptParser.is_custom_target( self, target )
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
|
-- [internal] Parse address according to family.
|
||||||
|
function IptParser._parse_addr( self, addr )
|
||||||
|
if self._family == 4 then
|
||||||
|
return luci.ip.IPv4(addr)
|
||||||
|
else
|
||||||
|
return luci.ip.IPv6(addr)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
-- [internal] Parse iptables output from all tables.
|
-- [internal] Parse iptables output from all tables.
|
||||||
function IptParser._parse_rules( self )
|
function IptParser._parse_rules( self )
|
||||||
|
|
||||||
for i, tbl in ipairs({ "filter", "nat", "mangle" }) do
|
for i, tbl in ipairs(self._tables) do
|
||||||
|
|
||||||
self._chains[tbl] = { }
|
self._chains[tbl] = { }
|
||||||
|
|
||||||
for i, rule in ipairs(luci.util.execl("iptables -t " .. tbl .. " --line-numbers -nxvL")) do
|
for i, rule in ipairs(luci.util.execl(self._command % tbl)) do
|
||||||
|
|
||||||
if rule:find( "Chain " ) == 1 then
|
if rule:find( "^Chain " ) == 1 then
|
||||||
|
|
||||||
local crefs
|
local crefs
|
||||||
local cname, cpol, cpkt, cbytes = rule:match(
|
local cname, cpol, cpkt, cbytes = rule:match(
|
||||||
"Chain ([^%s]*) %(policy (%w+) " ..
|
"^Chain ([^%s]*) %(policy (%w+) " ..
|
||||||
"(%d+) packets, (%d+) bytes%)"
|
"(%d+) packets, (%d+) bytes%)"
|
||||||
)
|
)
|
||||||
|
|
||||||
if not cname then
|
if not cname then
|
||||||
cname, crefs = rule:match(
|
cname, crefs = rule:match(
|
||||||
"Chain ([^%s]*) %((%d+) references%)"
|
"^Chain ([^%s]*) %((%d+) references%)"
|
||||||
)
|
)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue