-
Notifications
You must be signed in to change notification settings - Fork 4
/
Copy pathnfct-expect-create-userspace
executable file
·109 lines (77 loc) · 2.81 KB
/
nfct-expect-create-userspace
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
#!/usr/bin/lua
--[[
Rewrite of expect_create_userspace.c from libnetfilter_conntrack.
This example shows how to setup a user-space expectation. This requires
a Linux kernel >= 2.6.38.
]]
require"nfct"
function usage(k)
if arg[k] then
return
end
print("arg '"..k.."' not provided")
print("usage "..arg[0].." expect=port src=ip dst=ip sport=port dport=port [timeout=seconds] [flag=permanent]")
os.exit(1)
end
for i,a in ipairs(arg) do
local s,e,k,v = a:find("^([^=]+)=(.*)$")
arg[k] = v
end
for _,k in ipairs{"expect", "src", "dst", "sport", "dport", "timeout"} do
usage(k)
end
local assert = function(value, emsg, enum)
if value then
return value
end
error(emsg.." ["..(enum or "?").."]")
end
local function ctprint(ct, name, ...)
print("ct="..nfct.tostring(ct).." -- "..name, ...)
end
local function expprint(exp, name, ...)
print("exp="..nfct.exp_tostring(exp).." -- "..name, ...)
end
-- Setup master
master = assert(nfct.new())
assert(nfct.set_attr_pf (master, "l3proto", "inet"))
assert(nfct.set_attr_ipv4 (master, "ipv4-src", arg.src))
assert(nfct.set_attr_ipv4 (master, "ipv4-dst", arg.dst))
assert(nfct.set_attr_ipproto (master, "l4proto", "tcp"))
assert(nfct.set_attr_port (master, "port-src", arg.sport))
assert(nfct.set_attr_port (master, "port-dst", arg.dport))
ctprint(master, "master")
-- Setup expected
expected = assert(nfct.new())
assert(nfct.set_attr_pf (expected, "l3proto", "inet"))
assert(nfct.set_attr_ipv4 (expected, "ipv4-src", arg.src))
assert(nfct.set_attr_ipv4 (expected, "ipv4-dst", arg.dst))
assert(nfct.set_attr_ipproto (expected, "l4proto", "tcp"))
assert(nfct.set_attr_port (expected, "port-dst", arg.expect))
ctprint(expected, "expected")
-- Setup mask
mask = assert(nfct.new())
-- this mask value MUST be AF_INET or exp_query fails with ENOENT
assert(nfct.set_attr_pf (mask, "l3proto", "inet"))
assert(nfct.set_attr_u32 (mask, "ipv4-src", 0xffffffff))
assert(nfct.set_attr_u32 (mask, "ipv4-dst", 0xffffffff))
-- this mask value SHOULD be IPPROTO_TCP or ct object cannot be printed in full
assert(nfct.set_attr_ipproto (mask, "l4proto", "tcp"))
assert(nfct.set_attr_port (mask, "port-dst", 0xffff))
ctprint(mask, "mask")
-- Create expectation
exp = assert(nfct.exp_new(master, expected, mask, arg.timeout, arg.flag))
nfct.destroy(master)
nfct.destroy(expected)
nfct.destroy(mask)
expprint(exp, "expectation")
h = assert(nfct.open"expect")
-- FIXME this can fail if conntrack hasn't tracked the master... but is
-- that possible? we just got data from nfq, the connection must exist
local _, emsg, eno = nfct.exp_query(h, "create", exp)
if eno == 17 then
-- expectation already exists... normal?
else
assert(_, emsg)
end
nfct.close(h)