log.lua 2.68 KB
Newer Older
1 2
--[[
Packet logging module for Alpine Wall
3
Copyright (C) 2012-2017 Kaarle Ritvanen
4 5 6 7 8
See LICENSE file for license details
]]--


local model = require('awall.model')
9 10
local class = model.class

11
local combinations = require('awall.optfrag').combinations
12
local util = require('awall.util')
13 14 15 16 17


local LogLimit = class(model.Limit)

function LogLimit:init(...)
18
   util.setdefault(self, 'src-mask', false)
19 20
   LogLimit.super(self):init(...)
end
21 22


23
local Log = class(model.ConfigObject)
24

25 26
function Log:matchofrags()
   local selector, ofrags
27 28 29 30 31 32 33 34 35 36

   for i, sel in ipairs{'every', 'limit', 'probability'} do
      local value = self[sel]
      if value then
	 if selector then
	    self:error('Cannot combine '..sel..' with '..selector)
	 end
	 selector = sel

	 if sel == 'every' then
37
	    ofrags = {
38
	       {match='-m statistic --mode nth --every '..value..' --packet 0'}
39
	    }
40
	 elseif sel == 'limit' then
41
	    ofrags = self:create(LogLimit, value, 'loglimit'):limitofrags()
42
	 elseif sel == 'probability' then
43
	    ofrags = {{match='-m statistic --mode random --probability '..value}}
44 45 46 47
	 else assert(false) end
      end
   end

48 49 50 51 52
   if self.mode == 'ulog' then
      ofrags = combinations({{family='inet'}}, ofrags)
   end

   return ofrags
53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72
end

function Log:target()
   local optmap = {
      log={level='level', prefix='prefix'},
      nflog={
	 group='group',
	 prefix='prefix',
	 range='range',
	 threshold='threshold'
      },
      ulog={
	 group='nlgroup',
	 prefix='prefix',
	 range='cprange',
	 threshold='qthreshold'
      }
   }

   local mode = self.mode or 'log'
Kaarle Ritvanen's avatar
Kaarle Ritvanen committed
73
   if mode == 'none' then return end
74 75
   if not optmap[mode] then self:error('Invalid logging mode: '..mode) end

76
   local res = mode:upper()
77
   for s, t in pairs(optmap[mode]) do
78 79 80 81 82
      local value = self[s]
      if value then
	 if s == 'prefix' then value = util.quote(value) end
	 res = res..' --'..mode..'-'..t..' '..value
      end
83 84 85 86
   end
   return res
end

87
function Log:optfrags()
Kaarle Ritvanen's avatar
Kaarle Ritvanen committed
88 89
   local target = self:target()
   return combinations(self:matchofrags(), {target and {target=target}})
90
end
91 92 93 94 95 96 97 98 99

function Log.get(rule, spec, default)
   if spec == nil then spec = default end
   if spec == false then return end
   if spec == true then spec = '_default' end
   return rule.root.log[spec] or rule:error('Invalid log: '..spec)
end


100
local LogRule = class(model.Rule)
101 102

function LogRule:init(...)
103
   LogRule.super(self):init(...)
104 105 106 107 108
   self.log = Log.get(self, self.log, true)
end

function LogRule:position() return 'prepend' end

109 110
function LogRule:mangleoptfrags(ofrags)
   return combinations(ofrags, self.log:matchofrags())
111 112 113 114
end

function LogRule:target() return self.log:target() end

115 116 117 118 119

return {
   export={
      log={class=Log}, ['packet-log']={class=LogRule, after='%filter-after'}
   }
120
}