diff options
author | Sam Roberts <vieuxtech@gmail.com> | 2011-03-22 16:36:50 -0700 |
---|---|---|
committer | Sam Roberts <vieuxtech@gmail.com> | 2011-03-22 16:36:50 -0700 |
commit | 5f54e1df0fd4be7f5d6ce0baec9e92427e7e3d3e (patch) | |
tree | 646697ab3a2116db009ca7c6f2dec7a527149d94 | |
parent | 089b08195290c04f6fe140103d951d1ba1664dc9 (diff) | |
download | libnet-5f54e1df0fd4be7f5d6ce0baec9e92427e7e3d3e.tar.gz |
rewrite of libnfct's expect_create_userspace utility in lua
-rwxr-xr-x | lua/nfct-expect-create-userspace | 223 |
1 files changed, 223 insertions, 0 deletions
diff --git a/lua/nfct-expect-create-userspace b/lua/nfct-expect-create-userspace new file mode 100755 index 0000000..c8e8e90 --- /dev/null +++ b/lua/nfct-expect-create-userspace @@ -0,0 +1,223 @@ +#!/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") + os.exit(1) +end + +-- src=192.168.41.125 dst=74.125.155.113 sport=34645 dport=80 +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"} 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 + +--[[ + /* + * Step 1: Setup master conntrack + */ + + master = nfct_new(); + if (!master) { + perror("nfct_new"); + exit(EXIT_FAILURE); + } + + nfct_set_attr_u8(master, ATTR_L3PROTO, AF_INET); + nfct_set_attr_u32(master, ATTR_IPV4_SRC, inet_addr("1.1.1.1")); + nfct_set_attr_u32(master, ATTR_IPV4_DST, inet_addr("2.2.2.2")); + + nfct_set_attr_u8(master, ATTR_L4PROTO, IPPROTO_TCP); + nfct_set_attr_u16(master, ATTR_PORT_SRC, htons(1025)); + nfct_set_attr_u16(master, ATTR_PORT_DST, htons(21)); + + nfct_setobjopt(master, NFCT_SOPT_SETUP_REPLY); + + nfct_set_attr_u8(master, ATTR_TCP_STATE, TCP_CONNTRACK_ESTABLISHED); + nfct_set_attr_u32(master, ATTR_TIMEOUT, 200); +]] + +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)) + +assert(nfct.setobjopt(master, "setup-reply")) -- FIXME purpose of this is? +assert(nfct.set_attr_u8(master, "tcp-state", 3)) -- FIXME need to map enum tcp_state +assert(nfct.set_attr_u32(master, "timeout", 200)) + +ctprint(master, "master") + +--[[ + + h = nfct_open(CONNTRACK, 0); + if (!h) { + perror("nfct_open"); + return -1; + } + + /* + * In a real scenario in which you want to implement an helper in + * user-space with NFQUEUE, the master conntrack does not need to + * be created, since it should already exist. + */ + ret = nfct_query(h, NFCT_Q_CREATE, master); + + printf("TEST: add master conntrack "); + + if (ret == -1) + printf("(%d)(%s)\n", ret, strerror(errno)); + else + printf("(OK)\n"); + + nfct_close(h); +]] + +--[[ + expected = nfct_new(); + if (!expected) { + perror("nfct_new"); + exit(EXIT_FAILURE); + } + + nfct_set_attr_u8(expected, ATTR_L3PROTO, AF_INET); + nfct_set_attr_u32(expected, ATTR_IPV4_SRC, inet_addr("1.1.1.1")); + nfct_set_attr_u32(expected, ATTR_IPV4_DST, inet_addr("2.2.2.2")); + + nfct_set_attr_u8(expected, ATTR_L4PROTO, IPPROTO_TCP); + nfct_set_attr_u16(expected, ATTR_PORT_SRC, 0); + nfct_set_attr_u16(expected, ATTR_PORT_DST, htons(10241)); +]] + +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-src", 0)) +assert(nfct.set_attr_port (expected, "port-dst", arg.expect)) + +ctprint(expected, "expected") + +--[[ + mask = nfct_new(); + if (!mask) { + perror("nfct_new"); + exit(EXIT_FAILURE); + } + + nfct_set_attr_u8(mask, ATTR_L3PROTO, AF_INET); + nfct_set_attr_u32(mask, ATTR_IPV4_SRC, 0xffffffff); + nfct_set_attr_u32(mask, ATTR_IPV4_DST, 0xffffffff); + + nfct_set_attr_u8(mask, ATTR_L4PROTO, IPPROTO_TCP); + nfct_set_attr_u16(mask, ATTR_PORT_SRC, 0x0000); + nfct_set_attr_u16(mask, ATTR_PORT_DST, 0xffff); +]] + + +mask = assert(nfct.new()) + +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)) + +assert(nfct.set_attr_ipproto (mask, "l4proto", "tcp")) +assert(nfct.set_attr_port (mask, "port-src", 0)) +assert(nfct.set_attr_port (mask, "port-dst", 0xffff)) + +ctprint(mask, "mask") + +--[[ + /* + * Step 2: Setup expectation + */ + + exp = nfexp_new(); + if (!exp) { + perror("nfexp_new"); + exit(EXIT_FAILURE); + } + + nfexp_set_attr(exp, ATTR_EXP_MASTER, master); + nfexp_set_attr(exp, ATTR_EXP_EXPECTED, expected); + nfexp_set_attr(exp, ATTR_EXP_MASK, mask); + nfexp_set_attr_u32(exp, ATTR_EXP_TIMEOUT, 200); + + nfct_destroy(master); + nfct_destroy(expected); + nfct_destroy(mask); +]] + +exp = assert(nfct.exp_new(master, expected, mask, 200)) + +expprint(exp, "expectation") + +-- nfct.destroy(master) +-- nfct.destroy(expected) +-- nfct.destroy(mask) + +--[[ + h = nfct_open(EXPECT, 0); + if (!h) { + perror("nfct_open"); + return -1; + } + + ret = nfexp_query(h, NFCT_Q_CREATE, exp); +]] + +h = assert(nfct.open"expect") + +assert(nfct.exp_query(h, "create", exp)) + +--[[ + printf("TEST: create expectation "); + if (ret == -1) + printf("(%d)(%s)\n", ret, strerror(errno)); + else + printf("(OK)\n"); + + nfct_close(h); + + ret == -1 ? exit(EXIT_FAILURE) : exit(EXIT_SUCCESS); +} +]] + |