Globally reduce copyright headers
[project/luci.git] / applications / luci-app-firewall / luasrc / tools / firewall.lua
1 -- Copyright 2011-2012 Jo-Philipp Wich <xm@subsignal.org>
2 -- Licensed to the public under the Apache License 2.0.
3
4 module("luci.tools.firewall", package.seeall)
5
6 local ut = require "luci.util"
7 local ip = require "luci.ip"
8 local nx = require "nixio"
9
10 local translate, translatef = luci.i18n.translate, luci.i18n.translatef
11
12 local function tr(...)
13 return tostring(translate(...))
14 end
15
16 function fmt_neg(x)
17 if type(x) == "string" then
18 local v, neg = x:gsub("^ *! *", "")
19 if neg > 0 then
20 return v, "%s " % tr("not")
21 else
22 return x, ""
23 end
24 end
25 return x, ""
26 end
27
28 function fmt_mac(x)
29 if x and #x > 0 then
30 local m, n
31 local l = { tr("MAC"), " " }
32 for m in ut.imatch(x) do
33 m, n = fmt_neg(m)
34 l[#l+1] = "<var>%s%s</var>" %{ n, m }
35 l[#l+1] = ", "
36 end
37 if #l > 1 then
38 l[#l] = nil
39 if #l > 3 then
40 l[1] = tr("MACs")
41 end
42 return table.concat(l, "")
43 end
44 end
45 end
46
47 function fmt_port(x, d)
48 if x and #x > 0 then
49 local p, n
50 local l = { tr("port"), " " }
51 for p in ut.imatch(x) do
52 p, n = fmt_neg(p)
53 local a, b = p:match("(%d+)%D+(%d+)")
54 if a and b then
55 l[1] = tr("ports")
56 l[#l+1] = "<var>%s%d-%d</var>" %{ n, a, b }
57 else
58 l[#l+1] = "<var>%s%d</var>" %{ n, p }
59 end
60 l[#l+1] = ", "
61 end
62 if #l > 1 then
63 l[#l] = nil
64 if #l > 3 then
65 l[1] = tr("ports")
66 end
67 return table.concat(l, "")
68 end
69 end
70 return d and "<var>%s</var>" % d
71 end
72
73 function fmt_ip(x, d)
74 if x and #x > 0 then
75 local l = { tr("IP"), " " }
76 local v, a, n
77 for v in ut.imatch(x) do
78 v, n = fmt_neg(v)
79 a, m = v:match("(%S+)/(%d+%.%S+)")
80 a = a or v
81 a = a:match(":") and ip.IPv6(a, m) or ip.IPv4(a, m)
82 if a and (a:is6() and a:prefix() < 128 or a:prefix() < 32) then
83 l[1] = tr("IP range")
84 l[#l+1] = "<var title='%s - %s'>%s%s</var>" %{
85 a:minhost():string(),
86 a:maxhost():string(),
87 n, a:string()
88 }
89 else
90 l[#l+1] = "<var>%s%s</var>" %{
91 n,
92 a and a:string() or v
93 }
94 end
95 l[#l+1] = ", "
96 end
97 if #l > 1 then
98 l[#l] = nil
99 if #l > 3 then
100 l[1] = tr("IPs")
101 end
102 return table.concat(l, "")
103 end
104 end
105 return d and "<var>%s</var>" % d
106 end
107
108 function fmt_zone(x, d)
109 if x == "*" then
110 return "<var>%s</var>" % tr("any zone")
111 elseif x and #x > 0 then
112 return "<var>%s</var>" % x
113 elseif d then
114 return "<var>%s</var>" % d
115 end
116 end
117
118 function fmt_icmp_type(x)
119 if x and #x > 0 then
120 local t, v, n
121 local l = { tr("type"), " " }
122 for v in ut.imatch(x) do
123 v, n = fmt_neg(v)
124 l[#l+1] = "<var>%s%s</var>" %{ n, v }
125 l[#l+1] = ", "
126 end
127 if #l > 1 then
128 l[#l] = nil
129 if #l > 3 then
130 l[1] = tr("types")
131 end
132 return table.concat(l, "")
133 end
134 end
135 end
136
137 function fmt_proto(x, icmp_types)
138 if x and #x > 0 then
139 local v, n
140 local l = { }
141 local t = fmt_icmp_type(icmp_types)
142 for v in ut.imatch(x) do
143 v, n = fmt_neg(v)
144 if v == "tcpudp" then
145 l[#l+1] = "TCP"
146 l[#l+1] = ", "
147 l[#l+1] = "UDP"
148 l[#l+1] = ", "
149 elseif v ~= "all" then
150 local p = nx.getproto(v)
151 if p then
152 -- ICMP
153 if (p.proto == 1 or p.proto == 58) and t then
154 l[#l+1] = translatef(
155 "%s%s with %s",
156 n, p.aliases[1] or p.name, t
157 )
158 else
159 l[#l+1] = "%s%s" %{
160 n,
161 p.aliases[1] or p.name
162 }
163 end
164 l[#l+1] = ", "
165 end
166 end
167 end
168 if #l > 0 then
169 l[#l] = nil
170 return table.concat(l, "")
171 end
172 end
173 end
174
175 function fmt_limit(limit, burst)
176 burst = tonumber(burst)
177 if limit and #limit > 0 then
178 local l, u = limit:match("(%d+)/(%w+)")
179 l = tonumber(l or limit)
180 u = u or "second"
181 if l then
182 if u:match("^s") then
183 u = tr("second")
184 elseif u:match("^m") then
185 u = tr("minute")
186 elseif u:match("^h") then
187 u = tr("hour")
188 elseif u:match("^d") then
189 u = tr("day")
190 end
191 if burst and burst > 0 then
192 return translatef("<var>%d</var> pkts. per <var>%s</var>, \
193 burst <var>%d</var> pkts.", l, u, burst)
194 else
195 return translatef("<var>%d</var> pkts. per <var>%s</var>", l, u)
196 end
197 end
198 end
199 end
200
201 function fmt_target(x, dest)
202 if dest and #dest > 0 then
203 if x == "ACCEPT" then
204 return tr("Accept forward")
205 elseif x == "REJECT" then
206 return tr("Refuse forward")
207 elseif x == "NOTRACK" then
208 return tr("Do not track forward")
209 else --if x == "DROP" then
210 return tr("Discard forward")
211 end
212 else
213 if x == "ACCEPT" then
214 return tr("Accept input")
215 elseif x == "REJECT" then
216 return tr("Refuse input")
217 elseif x == "NOTRACK" then
218 return tr("Do not track input")
219 else --if x == "DROP" then
220 return tr("Discard input")
221 end
222 end
223 end
224
225
226 function opt_enabled(s, t, ...)
227 if t == luci.cbi.Button then
228 local o = s:option(t, "__enabled")
229 function o.render(self, section)
230 if self.map:get(section, "enabled") ~= "0" then
231 self.title = tr("Rule is enabled")
232 self.inputtitle = tr("Disable")
233 self.inputstyle = "reset"
234 else
235 self.title = tr("Rule is disabled")
236 self.inputtitle = tr("Enable")
237 self.inputstyle = "apply"
238 end
239 t.render(self, section)
240 end
241 function o.write(self, section, value)
242 if self.map:get(section, "enabled") ~= "0" then
243 self.map:set(section, "enabled", "0")
244 else
245 self.map:del(section, "enabled")
246 end
247 end
248 return o
249 else
250 local o = s:option(t, "enabled", ...)
251 o.default = "1"
252 return o
253 end
254 end
255
256 function opt_name(s, t, ...)
257 local o = s:option(t, "name", ...)
258
259 function o.cfgvalue(self, section)
260 return self.map:get(section, "name") or
261 self.map:get(section, "_name") or "-"
262 end
263
264 function o.write(self, section, value)
265 if value ~= "-" then
266 self.map:set(section, "name", value)
267 self.map:del(section, "_name")
268 else
269 self:remove(section)
270 end
271 end
272
273 function o.remove(self, section)
274 self.map:del(section, "name")
275 self.map:del(section, "_name")
276 end
277
278 return o
279 end