1 -- Copyright 2008 Steven Barth <steven@midlink.org>
2 -- Copyright 2010-2012 Jo-Philipp Wich <jow@openwrt.org>
3 -- Licensed to the public under the Apache License 2.0.
5 local sys = require "luci.sys"
6 local utl = require "luci.util"
7 local dsp = require "luci.dispatcher"
8 local nxo = require "nixio"
10 local ft = require "luci.tools.firewall"
11 local nw = require "luci.model.network"
17 translate("Firewall - Traffic Rules"),
18 translate("This page allows you to change advanced properties of the \
19 traffic rule entry, such as matched source and destination \
22 m.redirect = dsp.build_url("admin/network/firewall/rules")
26 local rule_type = m.uci:get("firewall", arg[1])
27 if rule_type == "redirect" and m:get(arg[1], "target") ~= "SNAT" then
32 luci.http.redirect(m.redirect)
38 elseif rule_type == "redirect" then
40 local name = m:get(arg[1], "name") or m:get(arg[1], "_name")
41 if not name or #name == 0 then
42 name = translate("(Unnamed SNAT)")
44 name = "SNAT %s" % name
47 m.title = "%s - %s" %{ translate("Firewall - Traffic Rules"), name }
51 m.uci:foreach("firewall", "zone",
53 local n = s.network or s.name
56 for i in utl.imatch(n) do
65 s = m:section(NamedSection, arg[1], "redirect", "")
70 ft.opt_enabled(s, Button)
71 ft.opt_name(s, Value, translate("Name"))
74 o = s:option(Value, "proto",
75 translate("Protocol"),
76 translate("You may specify multiple by selecting \"-- custom --\" and \
77 then entering protocols separated by space."))
79 o:value("all", "All protocols")
80 o:value("tcp udp", "TCP+UDP")
83 o:value("icmp", "ICMP")
85 function o.cfgvalue(...)
86 local v = Value.cfgvalue(...)
87 if not v or v == "tcpudp" then
94 o = s:option(Value, "src", translate("Source zone"))
97 o.template = "cbi/firewall_zonelist"
100 o = s:option(Value, "src_ip", translate("Source IP address"))
102 o.datatype = "neg(ipaddr)"
103 o.placeholder = translate("any")
105 luci.sys.net.ipv4_hints(function(ip, name)
106 o:value(ip, "%s (%s)" %{ ip, name })
110 o = s:option(Value, "src_port",
111 translate("Source port"),
112 translate("Match incoming traffic originating from the given source \
113 port or port range on the client host."))
115 o.datatype = "neg(portrange)"
116 o.placeholder = translate("any")
119 o = s:option(Value, "dest", translate("Destination zone"))
122 o.template = "cbi/firewall_zonelist"
125 o = s:option(Value, "dest_ip", translate("Destination IP address"))
126 o.datatype = "neg(ip4addr)"
128 luci.sys.net.ipv4_hints(function(ip, name)
129 o:value(ip, "%s (%s)" %{ ip, name })
133 o = s:option(Value, "dest_port",
134 translate("Destination port"),
135 translate("Match forwarded traffic to the given destination port or \
139 o.placeholder = translate("any")
140 o.datatype = "neg(portrange)"
143 o = s:option(Value, "src_dip",
144 translate("SNAT IP address"),
145 translate("Rewrite matched traffic to the given address."))
147 o.datatype = "ip4addr"
149 for k, v in ipairs(nw:get_interfaces()) do
151 for k, a in ipairs(v:ipaddrs()) do
152 o:value(a:host():string(), '%s (%s)' %{
153 a:host():string(), v:shortname()
159 o = s:option(Value, "src_dport", translate("SNAT port"),
160 translate("Rewrite matched traffic to the given source port. May be \
161 left empty to only rewrite the IP address."))
162 o.datatype = "portrange"
164 o.placeholder = translate('Do not rewrite')
167 s:option(Value, "extra",
168 translate("Extra arguments"),
169 translate("Passes additional arguments to iptables. Use with care!"))
176 local name = m:get(arg[1], "name") or m:get(arg[1], "_name")
177 if not name or #name == 0 then
178 name = translate("(Unnamed Rule)")
181 m.title = "%s - %s" %{ translate("Firewall - Traffic Rules"), name }
184 s = m:section(NamedSection, arg[1], "rule", "")
188 ft.opt_enabled(s, Button)
189 ft.opt_name(s, Value, translate("Name"))
192 o = s:option(ListValue, "family", translate("Restrict to address family"))
194 o:value("", translate("IPv4 and IPv6"))
195 o:value("ipv4", translate("IPv4 only"))
196 o:value("ipv6", translate("IPv6 only"))
199 o = s:option(Value, "proto", translate("Protocol"))
200 o:value("all", translate("Any"))
201 o:value("tcp udp", "TCP+UDP")
202 o:value("tcp", "TCP")
203 o:value("udp", "UDP")
204 o:value("icmp", "ICMP")
206 function o.cfgvalue(...)
207 local v = Value.cfgvalue(...)
208 if not v or v == "tcpudp" then
215 o = s:option(DynamicList, "icmp_type", translate("Match ICMP type"))
217 o:value("echo-reply")
218 o:value("destination-unreachable")
219 o:value("network-unreachable")
220 o:value("host-unreachable")
221 o:value("protocol-unreachable")
222 o:value("port-unreachable")
223 o:value("fragmentation-needed")
224 o:value("source-route-failed")
225 o:value("network-unknown")
226 o:value("host-unknown")
227 o:value("network-prohibited")
228 o:value("host-prohibited")
229 o:value("TOS-network-unreachable")
230 o:value("TOS-host-unreachable")
231 o:value("communication-prohibited")
232 o:value("host-precedence-violation")
233 o:value("precedence-cutoff")
234 o:value("source-quench")
236 o:value("network-redirect")
237 o:value("host-redirect")
238 o:value("TOS-network-redirect")
239 o:value("TOS-host-redirect")
240 o:value("echo-request")
241 o:value("router-advertisement")
242 o:value("router-solicitation")
243 o:value("time-exceeded")
244 o:value("ttl-zero-during-transit")
245 o:value("ttl-zero-during-reassembly")
246 o:value("parameter-problem")
247 o:value("ip-header-bad")
248 o:value("required-option-missing")
249 o:value("timestamp-request")
250 o:value("timestamp-reply")
251 o:value("address-mask-request")
252 o:value("address-mask-reply")
255 o = s:option(Value, "src", translate("Source zone"))
259 o.template = "cbi/firewall_zonelist"
262 o = s:option(Value, "src_mac", translate("Source MAC address"))
263 o.datatype = "list(macaddr)"
264 o.placeholder = translate("any")
266 luci.sys.net.mac_hints(function(mac, name)
267 o:value(mac, "%s (%s)" %{ mac, name })
271 o = s:option(Value, "src_ip", translate("Source address"))
272 o.datatype = "neg(ipaddr)"
273 o.placeholder = translate("any")
275 luci.sys.net.ipv4_hints(function(ip, name)
276 o:value(ip, "%s (%s)" %{ ip, name })
280 o = s:option(Value, "src_port", translate("Source port"))
281 o.datatype = "list(neg(portrange))"
282 o.placeholder = translate("any")
285 o = s:option(Value, "dest", translate("Destination zone"))
289 o.template = "cbi/firewall_zonelist"
292 o = s:option(Value, "dest_ip", translate("Destination address"))
293 o.datatype = "neg(ipaddr)"
294 o.placeholder = translate("any")
296 luci.sys.net.ipv4_hints(function(ip, name)
297 o:value(ip, "%s (%s)" %{ ip, name })
301 o = s:option(Value, "dest_port", translate("Destination port"))
302 o.datatype = "list(neg(portrange))"
303 o.placeholder = translate("any")
306 o = s:option(ListValue, "target", translate("Action"))
308 o:value("DROP", translate("drop"))
309 o:value("ACCEPT", translate("accept"))
310 o:value("REJECT", translate("reject"))
311 o:value("NOTRACK", translate("don't track"))
314 s:option(Value, "extra",
315 translate("Extra arguments"),
316 translate("Passes additional arguments to iptables. Use with care!"))
319 o = s:option(MultiValue, "weekdays", translate("Week Days"))
321 o.widget = "checkbox"
322 o:value("sun", translate("Sunday"))
323 o:value("mon", translate("Monday"))
324 o:value("tue", translate("Tuesday"))
325 o:value("wed", translate("Wednesday"))
326 o:value("thu", translate("Thursday"))
327 o:value("fri", translate("Friday"))
328 o:value("sat", translate("Saturday"))
330 o = s:option(MultiValue, "monthdays", translate("Month Days"))
332 o.widget = "checkbox"
334 o:value(translate(i))
337 o = s:option(Value, "start_time", translate("Start Time (hh:mm:ss)"))
338 o.datatype = "timehhmmss"
339 o = s:option(Value, "stop_time", translate("Stop Time (hh:mm:ss)"))
340 o.datatype = "timehhmmss"
341 o = s:option(Value, "start_date", translate("Start Date (yyyy-mm-dd)"))
342 o.datatype = "dateyyyymmdd"
343 o = s:option(Value, "stop_date", translate("Stop Date (yyyy-mm-dd)"))
344 o.datatype = "dateyyyymmdd"
346 o = s:option(Flag, "utc_time", translate("Time in UTC"))
347 o.default = o.disabled