libs/web: fix row sorting in IE
[project/luci.git] / applications / luci-firewall / luasrc / model / cbi / luci_fw / zones.lua
1 --[[
2 LuCI - Lua Configuration Interface
3
4 Copyright 2008 Steven Barth <steven@midlink.org>
5
6 Licensed under the Apache License, Version 2.0 (the "License");
7 you may not use this file except in compliance with the License.
8 You may obtain a copy of the License at
9
10         http://www.apache.org/licenses/LICENSE-2.0
11
12 $Id$
13 ]]--
14
15 local nw = require "luci.model.network"
16 local fw = require "luci.model.firewall"
17 local ds = require "luci.dispatcher"
18
19 local has_v2 = nixio.fs.access("/lib/firewall/fw.sh")
20
21 require("luci.tools.webadmin")
22 m = Map("firewall", translate("Firewall"), translate("The firewall creates zones over your network interfaces to control network traffic flow."))
23
24 fw.init(m.uci)
25 nw.init(m.uci)
26
27 s = m:section(TypedSection, "defaults")
28 s.anonymous = true
29 s.addremove = false
30
31 s:tab("general", translate("General Settings"))
32 s:tab("custom", translate("Custom Rules"))
33
34
35 s:taboption("general", Flag, "syn_flood", translate("Enable SYN-flood protection"))
36
37 local di = s:taboption("general", Flag, "drop_invalid", translate("Drop invalid packets"))
38 di.rmempty = false
39 function di.cfgvalue(...)
40         return AbstractValue.cfgvalue(...) or "1"
41 end
42
43 p = {}
44 p[1] = s:taboption("general", ListValue, "input", translate("Input"))
45 p[2] = s:taboption("general", ListValue, "output", translate("Output"))
46 p[3] = s:taboption("general", ListValue, "forward", translate("Forward"))
47
48 for i, v in ipairs(p) do
49         v:value("REJECT", translate("reject"))
50         v:value("DROP", translate("drop"))
51         v:value("ACCEPT", translate("accept"))
52 end
53
54 custom = s:taboption("custom", Value, "_custom",
55         translate("Custom Rules (/etc/firewall.user)"))
56
57 custom.template = "cbi/tvalue"
58 custom.rows = 20
59
60 function custom.cfgvalue(self, section)
61         return nixio.fs.readfile("/etc/firewall.user")
62 end
63
64 function custom.write(self, section, value)
65         value = value:gsub("\r\n?", "\n")
66         nixio.fs.writefile("/etc/firewall.user", value)
67 end
68
69
70 s = m:section(TypedSection, "zone", translate("Zones"))
71 s.template = "cbi/tblsection"
72 s.anonymous = true
73 s.addremove = true
74 s.extedit   = ds.build_url("admin", "network", "firewall", "zones", "%s")
75
76 function s.create(self)
77         local z = fw:new_zone()
78         if z then
79                 luci.http.redirect(
80                         ds.build_url("admin", "network", "firewall", "zones", z.sid)
81                 )
82         end
83 end
84
85 info = s:option(DummyValue, "_info", translate("Zone ⇒ Forwardings"))
86 info.template = "cbi/firewall_zoneforwards"
87 function info.cfgvalue(self, section)
88         return self.map:get(section, "name")
89 end
90
91 p = {}
92 p[1] = s:option(ListValue, "input", translate("Input"))
93 p[2] = s:option(ListValue, "output", translate("Output"))
94 p[3] = s:option(ListValue, "forward", translate("Forward"))
95
96 for i, v in ipairs(p) do
97         v:value("REJECT", translate("reject"))
98         v:value("DROP", translate("drop"))
99         v:value("ACCEPT", translate("accept"))
100 end
101
102 s:option(Flag, "masq", translate("Masquerading"))
103 s:option(Flag, "mtu_fix", translate("MSS clamping"))
104
105
106 local created = nil
107
108 --
109 -- Redirects
110 --
111
112 s = m:section(TypedSection, "redirect", translate("Redirections"))
113 s.template  = "cbi/tblsection"
114 s.addremove = true
115 s.anonymous = true
116 s.extedit   = ds.build_url("admin", "network", "firewall", "redirect", "%s")
117
118 function s.create(self, section)
119         created = TypedSection.create(self, section)
120 end
121
122 function s.parse(self, ...)
123         TypedSection.parse(self, ...)
124         if created then
125                 m.uci:save("firewall")
126                 luci.http.redirect(ds.build_url(
127                         "admin", "network", "firewall", "redirect", created
128                 ))
129         end
130 end
131
132 name = s:option(DummyValue, "_name", translate("Name"))
133 function name.cfgvalue(self, s)
134         return self.map:get(s, "_name") or "-"
135 end
136
137 proto = s:option(DummyValue, "proto", translate("Protocol"))
138 function proto.cfgvalue(self, s)
139         local p = self.map:get(s, "proto")
140         if not p or p == "tcpudp" then
141                 return "TCP+UDP"
142         else
143                 return p:upper()
144         end
145 end
146
147 src = s:option(DummyValue, "src", translate("Source"))
148 function src.cfgvalue(self, s)
149         local rv = "%s:%s:%s" % {
150                 self.map:get(s, "src") or "*",
151                 self.map:get(s, "src_ip") or "0.0.0.0/0",
152                 self.map:get(s, "src_port") or "*"
153         }
154
155         local mac = self.map:get(s, "src_mac")
156         if mac then
157                 rv = rv .. ", MAC " .. mac
158         end
159
160         return rv
161 end
162
163 via = s:option(DummyValue, "via", translate("Via"))
164 function via.cfgvalue(self, s)
165         return "%s:%s:%s" % {
166                 translate("Device"),
167                 self.map:get(s, "src_dip") or "0.0.0.0/0",
168                 self.map:get(s, "src_dport") or "*"
169         }
170 end
171
172 dest = s:option(DummyValue, "dest", translate("Destination"))
173 function dest.cfgvalue(self, s)
174         return "%s:%s:%s" % {
175                 self.map:get(s, "dest") or "*",
176                 self.map:get(s, "dest_ip") or "0.0.0.0/0",
177                 self.map:get(s, "dest_port") or "*"
178         }
179 end
180
181 target = s:option(DummyValue, "target", translate("Action"))
182 function target.cfgvalue(self, s)
183         return self.map:get(s, "target") or "DNAT"
184 end
185
186
187 --
188 -- Rules
189 --
190
191 s = m:section(TypedSection, "rule", translate("Rules"))
192 s.addremove = true
193 s.anonymous = true
194 s.template = "cbi/tblsection"
195 s.extedit   = ds.build_url("admin", "network", "firewall", "rule", "%s")
196 s.defaults.target = "ACCEPT"
197
198 function s.create(self, section)
199         local created = TypedSection.create(self, section)
200         m.uci:save("firewall")
201         luci.http.redirect(ds.build_url(
202                 "admin", "network", "firewall", "rule", created
203         ))
204         return
205 end
206
207 name = s:option(DummyValue, "_name", translate("Name"))
208 function name.cfgvalue(self, s)
209         return self.map:get(s, "_name") or "-"
210 end
211
212 if has_v2 then
213         family = s:option(DummyValue, "family", translate("Family"))
214         function family.cfgvalue(self, s)
215                 local f = self.map:get(s, "family")
216                 if f and f:match("4") then
217                         return translate("IPv4 only")
218                 elseif f and f:match("6") then
219                         return translate("IPv6 only")
220                 else
221                         return translate("IPv4 and IPv6")
222                 end
223         end
224 end
225
226 proto = s:option(DummyValue, "proto", translate("Protocol"))
227 function proto.cfgvalue(self, s)
228         local p = self.map:get(s, "proto")
229         local t = self.map:get(s, "icmp_type")
230         if p == "icmp" and t then
231                 return "ICMP (%s)" % t
232         elseif p == "tcpudp" or not p then
233                 return "TCP+UDP"
234         else
235                 return p:upper()
236         end
237 end
238
239 src = s:option(DummyValue, "src", translate("Source"))
240 function src.cfgvalue(self, s)
241         local rv = "%s:%s:%s" % {
242                 self.map:get(s, "src") or "*",
243                 self.map:get(s, "src_ip") or "0.0.0.0/0",
244                 self.map:get(s, "src_port") or "*"
245         }
246
247         local mac = self.map:get(s, "src_mac")
248         if mac then
249                 rv = rv .. ", MAC " .. mac
250         end
251
252         return rv
253 end
254
255 dest = s:option(DummyValue, "dest", translate("Destination"))
256 function dest.cfgvalue(self, s)
257         return "%s:%s:%s" % {
258                 self.map:get(s, "dest") or translate("Device"),
259                 self.map:get(s, "dest_ip") or "0.0.0.0/0",
260                 self.map:get(s, "dest_port") or "*"
261         }
262 end
263
264
265 s:option(DummyValue, "target", translate("Action"))
266
267 return m