firewall.lua 5.7 KB

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