From abebe7116f3205c7bf22febac11df7aca61fd818 Mon Sep 17 00:00:00 2001 From: Sam Roberts Date: Mon, 14 Feb 2011 17:19:44 -0800 Subject: Added nfexp_ APIs, and script to build tables of options. --- lua/luaopts | 93 ++++++++ lua/nfct.c | 774 +++++++++++++++++++++++++++++++++++++++++++----------------- lua/nflua.h | 268 +++++++++++++++++++++ lua/nfq.c | 22 +- 4 files changed, 926 insertions(+), 231 deletions(-) create mode 100755 lua/luaopts (limited to 'lua') diff --git a/lua/luaopts b/lua/luaopts new file mode 100755 index 0000000..7bedb11 --- /dev/null +++ b/lua/luaopts @@ -0,0 +1,93 @@ +#!/usr/bin/ruby -w + +pattern = ARGV.shift + +RXDEF = %r{^\s*(?:[#]\s*define)?\s*#{pattern}_(\w+)(.*)} +RXDOC = %r{/[/*](.*)} + + +OPTS = [] + +ARGF.each do |line| + next unless line =~ RXDEF + + name = $1 + doc = nil + + if $2 =~ RXDOC + doc = $1.gsub(/\*\/.*/, "").strip + end + + #p [name, doc, line] + + next if name == "MAX" + + cname = pattern + "_" + name + lname = name.gsub(/_/, "-").downcase + +=begin +Catch cases like: + +enum + { + IPPROTO_IP = 0, /* Dummy protocol for TCP. */ +#define IPPROTO_IP IPPROTO_IP +=end + + if OPTS.last and OPTS.last[1] == cname + if not OPTS.last[2] + OPTS.last[2] = doc + end + next + end + + OPTS << [lname, cname, doc] + + #p OPTS.last +end + +width = 10 + +OPTS.each do |lname, cname, doc| + if lname.size > width + width = lname.size + 2 + end +end + +puts "-- DOCUMENTATION" + +OPTS.each do |lname, cname, doc| + line = " #{lname}#{" " * (width - lname.size)}-- #{cname}" + if doc + line << ", #{doc}" + end + puts line +end + +puts"" +puts"" + +puts "static const char* " + pattern + "_opts[] = {" + +OPTS.each do |lname, cname, doc| + puts " #{lname.inspect}," +end +puts " NULL" +puts "};" + +puts "static int " + pattern + "_vals[] = {" +OPTS.each do |lname, cname, doc| + puts " #{cname}," +end +puts "};" +puts "static int " + pattern + "_vals_size = " + OPTS.size.to_s + ";" + +puts <<__ +static int check_#{pattern}(lua_State* L, int argn) +{ + int opt = luaL_checkoption(L, argn, NULL /* default? */, #{pattern}_opts); + int val = #{pattern}_vals[opt]; + return val; +} +__ + diff --git a/lua/nfct.c b/lua/nfct.c index 7eb1e9e..334ce94 100644 --- a/lua/nfct.c +++ b/lua/nfct.c @@ -29,11 +29,14 @@ THE POSSIBILITY OF SUCH DAMAGE. ** nfct - a binding to netfilter's conntrack subsystem NOTE I know its confusing that the nfct module has functions that should be -called on a conntrack handle and a conntrack context mixed together, but unless -I make full userdata out of one or both of them, thats what it has to be. Don't -confuse them, or you will segfault! +called on different kinds of objects mixed together, but unless I make full +userdata out of one or both of them, thats what it has to be. Don't confuse +them, or you will segfault! */ +#define WANT_NF_LUA_PF +#define WANT_NF_LUA_PF_PUSH +#define WANT_NF_LUA_IPPROTO #include "nflua.h" #include @@ -50,15 +53,29 @@ static struct nfct_handle* check_cthandle(lua_State*L) return cth; } -static struct nf_conntrack* check_ct(lua_State*L) +static struct nf_conntrack* check_ct_argn(lua_State*L, int argn, const char* emsg) { struct nf_conntrack* ct = lua_touserdata(L, 1); - luaL_argcheck(L, ct, 1, "conntrack not provided"); + luaL_argcheck(L, ct, argn, emsg); return ct; } +static struct nf_conntrack* check_ct(lua_State*L) +{ + return check_ct_argn(L, 1, "conntrack not provided"); +} + +static struct nf_expect* check_exp(lua_State* L, int argn) +{ + struct nf_expect* exp = lua_touserdata(L, argn); + + luaL_argcheck(L, exp, argn, "expect not provided"); + + return exp; +} + static const char* ctmsg_type_string(enum nf_conntrack_msg_type type) { switch(type) { @@ -71,6 +88,229 @@ static const char* ctmsg_type_string(enum nf_conntrack_msg_type type) } +static const char* ATTR_opts[] = { + "orig-ipv4-src", + "ipv4-src", + "orig-ipv4-dst", + "ipv4-dst", + "repl-ipv4-src", + "repl-ipv4-dst", + "orig-ipv6-src", + "ipv6-src", + "orig-ipv6-dst", + "ipv6-dst", + "repl-ipv6-src", + "repl-ipv6-dst", + "orig-port-src", + "port-src", + "orig-port-dst", + "port-dst", + "repl-port-src", + "repl-port-dst", + "icmp-type", + "icmp-code", + "icmp-id", + "orig-l3proto", + "l3proto", + "repl-l3proto", + "orig-l4proto", + "l4proto", + "repl-l4proto", + "tcp-state", + "snat-ipv4", + "dnat-ipv4", + "snat-port", + "dnat-port", + "timeout", + "mark", + "orig-counter-packets", + "repl-counter-packets", + "orig-counter-bytes", + "repl-counter-bytes", + "use", + "id", + "status", + "tcp-flags-orig", + "tcp-flags-repl", + "tcp-mask-orig", + "tcp-mask-repl", + "master-ipv4-src", + "master-ipv4-dst", + "master-ipv6-src", + "master-ipv6-dst", + "master-port-src", + "master-port-dst", + "master-l3proto", + "master-l4proto", + "secmark", + "orig-nat-seq-correction-pos", + "orig-nat-seq-offset-before", + "orig-nat-seq-offset-after", + "repl-nat-seq-correction-pos", + "repl-nat-seq-offset-before", + "repl-nat-seq-offset-after", + "sctp-state", + "sctp-vtag-orig", + "sctp-vtag-repl", + "helper-name", + "dccp-state", + "dccp-role", + "dccp-handshake-seq", + "grp-orig-ipv4", + "grp-repl-ipv4", + "grp-orig-ipv6", + "grp-repl-ipv6", + "grp-orig-port", + "grp-repl-port", + "grp-icmp", + "grp-master-ipv4", + "grp-master-ipv6", + "grp-master-port", + "grp-orig-counters", + "grp-repl-counters", + "grp-max", + "exp-master", + "exp-expected", + "exp-mask", + "exp-timeout", + "exp-max", + NULL +}; + +static int ATTR_vals[] = { + ATTR_ORIG_IPV4_SRC, + ATTR_IPV4_SRC, + ATTR_ORIG_IPV4_DST, + ATTR_IPV4_DST, + ATTR_REPL_IPV4_SRC, + ATTR_REPL_IPV4_DST, + ATTR_ORIG_IPV6_SRC, + ATTR_IPV6_SRC, + ATTR_ORIG_IPV6_DST, + ATTR_IPV6_DST, + ATTR_REPL_IPV6_SRC, + ATTR_REPL_IPV6_DST, + ATTR_ORIG_PORT_SRC, + ATTR_PORT_SRC, + ATTR_ORIG_PORT_DST, + ATTR_PORT_DST, + ATTR_REPL_PORT_SRC, + ATTR_REPL_PORT_DST, + ATTR_ICMP_TYPE, + ATTR_ICMP_CODE, + ATTR_ICMP_ID, + ATTR_ORIG_L3PROTO, + ATTR_L3PROTO, + ATTR_REPL_L3PROTO, + ATTR_ORIG_L4PROTO, + ATTR_L4PROTO, + ATTR_REPL_L4PROTO, + ATTR_TCP_STATE, + ATTR_SNAT_IPV4, + ATTR_DNAT_IPV4, + ATTR_SNAT_PORT, + ATTR_DNAT_PORT, + ATTR_TIMEOUT, + ATTR_MARK, + ATTR_ORIG_COUNTER_PACKETS, + ATTR_REPL_COUNTER_PACKETS, + ATTR_ORIG_COUNTER_BYTES, + ATTR_REPL_COUNTER_BYTES, + ATTR_USE, + ATTR_ID, + ATTR_STATUS, + ATTR_TCP_FLAGS_ORIG, + ATTR_TCP_FLAGS_REPL, + ATTR_TCP_MASK_ORIG, + ATTR_TCP_MASK_REPL, + ATTR_MASTER_IPV4_SRC, + ATTR_MASTER_IPV4_DST, + ATTR_MASTER_IPV6_SRC, + ATTR_MASTER_IPV6_DST, + ATTR_MASTER_PORT_SRC, + ATTR_MASTER_PORT_DST, + ATTR_MASTER_L3PROTO, + ATTR_MASTER_L4PROTO, + ATTR_SECMARK, + ATTR_ORIG_NAT_SEQ_CORRECTION_POS, + ATTR_ORIG_NAT_SEQ_OFFSET_BEFORE, + ATTR_ORIG_NAT_SEQ_OFFSET_AFTER, + ATTR_REPL_NAT_SEQ_CORRECTION_POS, + ATTR_REPL_NAT_SEQ_OFFSET_BEFORE, + ATTR_REPL_NAT_SEQ_OFFSET_AFTER, + ATTR_SCTP_STATE, + ATTR_SCTP_VTAG_ORIG, + ATTR_SCTP_VTAG_REPL, + ATTR_HELPER_NAME, + ATTR_DCCP_STATE, + ATTR_DCCP_ROLE, + ATTR_DCCP_HANDSHAKE_SEQ, + ATTR_GRP_ORIG_IPV4, + ATTR_GRP_REPL_IPV4, + ATTR_GRP_ORIG_IPV6, + ATTR_GRP_REPL_IPV6, + ATTR_GRP_ORIG_PORT, + ATTR_GRP_REPL_PORT, + ATTR_GRP_ICMP, + ATTR_GRP_MASTER_IPV4, + ATTR_GRP_MASTER_IPV6, + ATTR_GRP_MASTER_PORT, + ATTR_GRP_ORIG_COUNTERS, + ATTR_GRP_REPL_COUNTERS, + ATTR_GRP_MAX, + ATTR_EXP_MASTER, + ATTR_EXP_EXPECTED, + ATTR_EXP_MASK, + ATTR_EXP_TIMEOUT, + ATTR_EXP_MAX, +}; + +/*static int ATTR_vals_size = 85;*/ +static int check_ATTR(lua_State* L, int argn) +{ + int opt = luaL_checkoption(L, argn, NULL /* default? */, ATTR_opts); + int val = ATTR_vals[opt]; + return val; +} + +static enum nf_conntrack_attr check_attr(lua_State* L) +{ + return check_ATTR(L, 2); +} + + +static const char* NFCT_Q_opts[] = { + "create", + "update", + "destroy", + "get", + "flush", + "dump", + "dump-reset", + "create-update", + NULL +}; + +static int NFCT_Q_vals[] = { + NFCT_Q_CREATE, + NFCT_Q_UPDATE, + NFCT_Q_DESTROY, + NFCT_Q_GET, + NFCT_Q_FLUSH, + NFCT_Q_DUMP, + NFCT_Q_DUMP_RESET, + NFCT_Q_CREATE_UPDATE, +}; + +/*static int NFCT_Q_vals_size = 8;*/ +static int check_NFCT_Q(lua_State* L, int argn) +{ + int opt = luaL_checkoption(L, argn, NULL /* default? */, NFCT_Q_opts); + int val = NFCT_Q_vals[opt]; + return val; +} + + /*- -- cthandle = nfct.open(subsys, [subscription...]) @@ -125,7 +365,7 @@ static int hopen(lua_State *L) assert(subsys_opt == 0 || subsys_opt == 1); for(narg = 2; narg <= lua_gettop(L); narg++) { - int subscription_opt = luaL_checkoption(L, narg, "none", subscription_opts); + int subscription_opt = luaL_checkoption(L, narg, NULL, subscription_opts); subscription_val |= subscription_vals[subsys_opt][subscription_opt]; } @@ -389,7 +629,7 @@ Sets an option on a conntrack context, option is one of: Returns ct on success so calls can be chained, and nil,emsg,errno on failure. */ -int setobjopt(lua_State* L) +static int setobjopt(lua_State* L) { struct nf_conntrack* ct = check_ct(L); static const char* opts[] = { @@ -420,137 +660,6 @@ int setobjopt(lua_State* L) return 1; } -static const char* attr_opts[] = { - "orig-ipv4-src", - "orig-ipv4-dst", - "repl-ipv4-src", - "repl-ipv4-dst", - "orig-ipv6-src", - "orig-ipv6-dst", - "repl-ipv6-src", - "repl-ipv6-dst", - "orig-port-src", - "orig-port-dst", - "repl-port-src", - "repl-port-dst", - "icmp-type", - "icmp-code", - "icmp-id", - "orig-l3proto", - "repl-l3proto", - "orig-l4proto", - "repl-l4proto", - "tcp-state", - "snat-ipv4", - "dnat-ipv4", - "snat-port", - "dnat-port", - "timeout", - "mark", - "orig-counter-packets", - "repl-counter-packets", - "orig-counter-bytes", - "repl-counter-bytes", - "use", - "id", - "status", - "tcp-flags-orig", - "tcp-flags-repl", - "tcp-mask-orig", - "tcp-mask-repl", - "master-ipv4-src", - "master-ipv4-dst", - "master-ipv6-src", - "master-ipv6-dst", - "master-port-src", - "master-port-dst", - "master-l3proto", - "master-l4proto", - "secmark", - "orig-nat-seq-correction-pos", - "orig-nat-seq-offset-before", - "orig-nat-seq-offset-after", - "repl-nat-seq-correction-pos", - "repl-nat-seq-offset-before", - "repl-nat-seq-offset-after", - "sctp-state", - "sctp-vtag-orig", - "sctp-vtag-repl", - "helper-name", - "dccp-state", - "dccp-role", - "dccp-handshake-seq", -}; - -enum nf_conntrack_attr attr_vals[] = { - ATTR_ORIG_IPV4_SRC, - ATTR_ORIG_IPV4_DST, - ATTR_REPL_IPV4_SRC, - ATTR_REPL_IPV4_DST, - ATTR_ORIG_IPV6_SRC, - ATTR_ORIG_IPV6_DST, - ATTR_REPL_IPV6_SRC, - ATTR_REPL_IPV6_DST, - ATTR_ORIG_PORT_SRC, - ATTR_ORIG_PORT_DST, - ATTR_REPL_PORT_SRC, - ATTR_REPL_PORT_DST, - ATTR_ICMP_TYPE, - ATTR_ICMP_CODE, - ATTR_ICMP_ID, - ATTR_ORIG_L3PROTO, - ATTR_REPL_L3PROTO, - ATTR_ORIG_L4PROTO, - ATTR_REPL_L4PROTO, - ATTR_TCP_STATE, - ATTR_SNAT_IPV4, - ATTR_DNAT_IPV4, - ATTR_SNAT_PORT, - ATTR_DNAT_PORT, - ATTR_TIMEOUT, - ATTR_MARK, - ATTR_ORIG_COUNTER_PACKETS, - ATTR_REPL_COUNTER_PACKETS, - ATTR_ORIG_COUNTER_BYTES, - ATTR_REPL_COUNTER_BYTES, - ATTR_USE, - ATTR_ID, - ATTR_STATUS, - ATTR_TCP_FLAGS_ORIG, - ATTR_TCP_FLAGS_REPL, - ATTR_TCP_MASK_ORIG, - ATTR_TCP_MASK_REPL, - ATTR_MASTER_IPV4_SRC, - ATTR_MASTER_IPV4_DST, - ATTR_MASTER_IPV6_SRC, - ATTR_MASTER_IPV6_DST, - ATTR_MASTER_PORT_SRC, - ATTR_MASTER_PORT_DST, - ATTR_MASTER_L3PROTO, - ATTR_MASTER_L4PROTO, - ATTR_SECMARK, - ATTR_ORIG_NAT_SEQ_CORRECTION_POS, - ATTR_ORIG_NAT_SEQ_OFFSET_BEFORE, - ATTR_ORIG_NAT_SEQ_OFFSET_AFTER, - ATTR_REPL_NAT_SEQ_CORRECTION_POS, - ATTR_REPL_NAT_SEQ_OFFSET_BEFORE, - ATTR_REPL_NAT_SEQ_OFFSET_AFTER, - ATTR_SCTP_STATE, - ATTR_SCTP_VTAG_ORIG, - ATTR_SCTP_VTAG_REPL, - ATTR_HELPER_NAME, - ATTR_DCCP_STATE, - ATTR_DCCP_ROLE, - ATTR_DCCP_HANDSHAKE_SEQ, -}; - -static enum nf_conntrack_attr check_attr(lua_State* L) -{ - int attr_opt = luaL_checkoption(L, 2, NULL, attr_opts); - enum nf_conntrack_attr attr_val = attr_vals[attr_opt]; - return attr_val; -} - /* TODO get_attr_ip() -- ip in presentation format @@ -578,78 +687,85 @@ to host byte order. get_attr_port() is an alias for get_attr_n16(), since TCP and UDP ports are n16. -attr is one of: - "orig-ipv4-src", -- u32 bits - "orig-ipv4-dst", -- u32 bits - "repl-ipv4-src", -- u32 bits - "repl-ipv4-dst", -- u32 bits - "orig-ipv6-src", -- u128 bits - "orig-ipv6-dst", -- u128 bits - "repl-ipv6-src", -- u128 bits - "repl-ipv6-dst", -- u128 bits - "orig-port-src", -- u16 bits - "orig-port-dst", -- u16 bits - "repl-port-src", -- u16 bits - "repl-port-dst", -- u16 bits - "icmp-type", -- u8 bits - "icmp-code", -- u8 bits - "icmp-id", -- u16 bits - "orig-l3proto", -- u8 bits - "repl-l3proto", -- u8 bits - "orig-l4proto", -- u8 bits - "repl-l4proto", -- u8 bits - "tcp-state", -- u8 bits - "snat-ipv4", -- u32 bits - "dnat-ipv4", -- u32 bits - "snat-port", -- u16 bits - "dnat-port", -- u16 bits - "timeout", -- u32 bits - "mark", -- u32 bits - "orig-counter-packets", -- u32 bits - "repl-counter-packets", -- u32 bits - "orig-counter-bytes", -- u32 bits - "repl-counter-bytes", -- u32 bits - "use", -- u32 bits - "id", -- u32 bits - "status", -- u32 bits - "tcp-flags-orig", -- u8 bits - "tcp-flags-repl", -- u8 bits - "tcp-mask-orig", -- u8 bits - "tcp-mask-repl", -- u8 bits - "master-ipv4-src", -- u32 bits - "master-ipv4-dst", -- u32 bits - "master-ipv6-src", -- u128 bits - "master-ipv6-dst", -- u128 bits - "master-port-src", -- u16 bits - "master-port-dst", -- u16 bits - "master-l3proto", -- u8 bits - "master-l4proto", -- u8 bits - "secmark", -- u32 bits - "orig-nat-seq-correction-pos", -- u32 bits - "orig-nat-seq-offset-before", -- u32 bits - "orig-nat-seq-offset-after", -- u32 bits - "repl-nat-seq-correction-pos", -- u32 bits - "repl-nat-seq-offset-before", -- u32 bits - "repl-nat-seq-offset-after", -- u32 bits - "sctp-state", -- u8 bits - "sctp-vtag-orig", -- u32 bits - "sctp-vtag-repl", -- u32 bits - "helper-name", -- string (30 bytes max) - "dccp-state", -- u8 bits - "dccp-role", -- u8 bits - "dccp-handshake-seq", -- u64 bits - -See enum nf_conntrack_attr (the aliases are not supported) +attr is one of the enum nf_conntrack_attr values, where some aliases are +provided for the more commonly used origin attributes: + orig-ipv4-src -- ATTR_ORIG_IPV4_SRC, u32 bits + ipv4-src -- ATTR_IPV4_SRC, alias + orig-ipv4-dst -- ATTR_ORIG_IPV4_DST, u32 bits + ipv4-dst -- ATTR_IPV4_DST, alias + repl-ipv4-src -- ATTR_REPL_IPV4_SRC, u32 bits + repl-ipv4-dst -- ATTR_REPL_IPV4_DST, u32 bits + orig-ipv6-src -- ATTR_ORIG_IPV6_SRC, u128 bits + ipv6-src -- ATTR_IPV6_SRC, alias + orig-ipv6-dst -- ATTR_ORIG_IPV6_DST, u128 bits + ipv6-dst -- ATTR_IPV6_DST, alias + repl-ipv6-src -- ATTR_REPL_IPV6_SRC, u128 bits + repl-ipv6-dst -- ATTR_REPL_IPV6_DST, u128 bits + orig-port-src -- ATTR_ORIG_PORT_SRC, u16 bits + port-src -- ATTR_PORT_SRC, alias + orig-port-dst -- ATTR_ORIG_PORT_DST, u16 bits + port-dst -- ATTR_PORT_DST, alias + repl-port-src -- ATTR_REPL_PORT_SRC, u16 bits + repl-port-dst -- ATTR_REPL_PORT_DST, u16 bits + icmp-type -- ATTR_ICMP_TYPE, u8 bits + icmp-code -- ATTR_ICMP_CODE, u8 bits + icmp-id -- ATTR_ICMP_ID, u16 bits + orig-l3proto -- ATTR_ORIG_L3PROTO, u8 bits + l3proto -- ATTR_L3PROTO, alias + repl-l3proto -- ATTR_REPL_L3PROTO, u8 bits + orig-l4proto -- ATTR_ORIG_L4PROTO, u8 bits + l4proto -- ATTR_L4PROTO, alias + repl-l4proto -- ATTR_REPL_L4PROTO, u8 bits + tcp-state -- ATTR_TCP_STATE, u8 bits + snat-ipv4 -- ATTR_SNAT_IPV4, u32 bits + dnat-ipv4 -- ATTR_DNAT_IPV4, u32 bits + snat-port -- ATTR_SNAT_PORT, u16 bits + dnat-port -- ATTR_DNAT_PORT, u16 bits + timeout -- ATTR_TIMEOUT, u32 bits + mark -- ATTR_MARK, u32 bits + orig-counter-packets -- ATTR_ORIG_COUNTER_PACKETS, u32 bits + repl-counter-packets -- ATTR_REPL_COUNTER_PACKETS, u32 bits + orig-counter-bytes -- ATTR_ORIG_COUNTER_BYTES, u32 bits + repl-counter-bytes -- ATTR_REPL_COUNTER_BYTES, u32 bits + use -- ATTR_USE, u32 bits + id -- ATTR_ID, u32 bits + status -- ATTR_STATUS, u32 bits + tcp-flags-orig -- ATTR_TCP_FLAGS_ORIG, u8 bits + tcp-flags-repl -- ATTR_TCP_FLAGS_REPL, u8 bits + tcp-mask-orig -- ATTR_TCP_MASK_ORIG, u8 bits + tcp-mask-repl -- ATTR_TCP_MASK_REPL, u8 bits + master-ipv4-src -- ATTR_MASTER_IPV4_SRC, u32 bits + master-ipv4-dst -- ATTR_MASTER_IPV4_DST, u32 bits + master-ipv6-src -- ATTR_MASTER_IPV6_SRC, u128 bits + master-ipv6-dst -- ATTR_MASTER_IPV6_DST, u128 bits + master-port-src -- ATTR_MASTER_PORT_SRC, u16 bits + master-port-dst -- ATTR_MASTER_PORT_DST, u16 bits + master-l3proto -- ATTR_MASTER_L3PROTO, u8 bits + master-l4proto -- ATTR_MASTER_L4PROTO, u8 bits + secmark -- ATTR_SECMARK, u32 bits + orig-nat-seq-correction-pos -- ATTR_ORIG_NAT_SEQ_CORRECTION_POS, u32 bits + orig-nat-seq-offset-before -- ATTR_ORIG_NAT_SEQ_OFFSET_BEFORE, u32 bits + orig-nat-seq-offset-after -- ATTR_ORIG_NAT_SEQ_OFFSET_AFTER, u32 bits + repl-nat-seq-correction-pos -- ATTR_REPL_NAT_SEQ_CORRECTION_POS, u32 bits + repl-nat-seq-offset-before -- ATTR_REPL_NAT_SEQ_OFFSET_BEFORE, u32 bits + repl-nat-seq-offset-after -- ATTR_REPL_NAT_SEQ_OFFSET_AFTER, u32 bits + sctp-state -- ATTR_SCTP_STATE, u8 bits + sctp-vtag-orig -- ATTR_SCTP_VTAG_ORIG, u32 bits + sctp-vtag-repl -- ATTR_SCTP_VTAG_REPL, u32 bits + helper-name -- ATTR_HELPER_NAME, string (30 bytes max) + dccp-state -- ATTR_DCCP_STATE, u8 bits + dccp-role -- ATTR_DCCP_ROLE, u8 bits + dccp-handshake-seq -- ATTR_DCCP_HANDSHAKE_SEQ, u64 bits + */ -/* FIXME - I really need the aliases back in, they aren't just for backwards - * compatibility, they are the best names to use, usually. - */ + /*- -- ct = nfct.set_attr_u8(ct, attr, value) -- ct = nfct.set_attr_u16(ct, attr, value) -- ct = nfct.set_attr_u32(ct, attr, value) -- ct = nfct.set_attr_n16(ct, attr, value) -- ct = nfct.set_attr_n32(ct, attr, value) +-- ct = nfct.set_attr_port(ct, attr, value) No error checking is done, value will be cast to the necessary type, and who knows what will happen for values that aren't actually of the correct type for @@ -706,8 +822,6 @@ ATTR_UX(n16) ATTR_UX(n32) /*- --- value = nfct.get_attr_ipv4(ct, attr) --- value = nfct.get_attr_ipv6(ct, attr) -- ct = nfct.set_attr_ipv4(ct, attr, value) Get an attribute as a string, the internet address in presentation format. @@ -741,6 +855,16 @@ static int get_attr_ipv6(lua_State* L) nfct_get_attr(check_ct(L), check_attr(L))); } +/*- +-- ct = nfct.set_attr_ipv4(ct, attr, value) +-- ct = nfct.set_attr_ipv6(ct, attr, value) + +Set an attribute as a string, the internet address in presentation format. + +See inet_ntop(3) for more information. + +Returns the conntrack conntext, so calls can be chained. +*/ static int set_attr_ipvx(lua_State* L, int af) { unsigned char buf[sizeof(struct in6_addr)]; @@ -766,6 +890,217 @@ static int set_attr_ipv6(lua_State* L) return set_attr_ipvx(L, AF_INET6); } +/*- +-- value = nfct.get_attr_pf(ct, attr) +-- ct = nfct.set_attr_pf(ct, attr, value) + +Set or get attributes with address family/protocol values as a string, for +example, the "l3proto". + +The address families, such as AF_INET and AF_INET6, are defined in the system +headers to be identical to the equivalent protocol family. + +Value is one of: + unspec -- PF_UNSPEC, Unspecified. + local -- PF_LOCAL, Local to host (pipes and file-domain). + unix -- PF_UNIX, POSIX name for PF_LOCAL. + file -- PF_FILE, Another non-standard name for PF_LOCAL. + inet -- PF_INET, IP protocol family. + ax25 -- PF_AX25, Amateur Radio AX.25. + ipx -- PF_IPX, Novell Internet Protocol. + appletalk -- PF_APPLETALK, Appletalk DDP. + netrom -- PF_NETROM, Amateur radio NetROM. + bridge -- PF_BRIDGE, Multiprotocol bridge. + atmpvc -- PF_ATMPVC, ATM PVCs. + x25 -- PF_X25, Reserved for X.25 project. + inet6 -- PF_INET6, IP version 6. + rose -- PF_ROSE, Amateur Radio X.25 PLP. + decnet -- PF_DECnet, Reserved for DECnet project. + netbeui -- PF_NETBEUI, Reserved for 802.2LLC project. + security -- PF_SECURITY, Security callback pseudo AF. + key -- PF_KEY, PF_KEY key management API. + netlink -- PF_NETLINK + route -- PF_ROUTE, Alias to emulate 4.4BSD. + packet -- PF_PACKET, Packet family. + ash -- PF_ASH, Ash. + econet -- PF_ECONET, Acorn Econet. + atmsvc -- PF_ATMSVC, ATM SVCs. + rds -- PF_RDS, RDS sockets. + sna -- PF_SNA, Linux SNA Project + irda -- PF_IRDA, IRDA sockets. + pppox -- PF_PPPOX, PPPoX sockets. + wanpipe -- PF_WANPIPE, Wanpipe API sockets. + llc -- PF_LLC, Linux LLC. + can -- PF_CAN, Controller Area Network. + tipc -- PF_TIPC, TIPC sockets. + bluetooth -- PF_BLUETOOTH, Bluetooth sockets. + iucv -- PF_IUCV, IUCV sockets. + rxrpc -- PF_RXRPC, RxRPC sockets. + isdn -- PF_ISDN, mISDN sockets. + phonet -- PF_PHONET, Phonet sockets. + ieee802154-- PF_IEEE802154, IEEE 802.15.4 sockets. + +Get returns the value as a string if it is known, or a number if it is not. + +Set returns the conntrack conntext, so calls can be chained. +*/ +static int get_attr_pf(lua_State* L) +{ + push_PF(L, + nfct_get_attr_u8(check_ct(L), check_attr(L))); + return 1; +} +static int set_attr_pf(lua_State* L) +{ + nfct_set_attr_u8( + check_ct(L), + check_attr(L), + check_PF(L,3)); + lua_settop(L, 1); + return 1; +} + +/*- +-- value = nfct.get_attr_ipproto(ct, attr) +-- ct = nfct.set_attr_ipproto(ct, attr, value) + +Set or get attributes with IP protocol values as a string, for example, the +"l4proto" attribute if the "l3proto" is "inet" or "inet6". + +Value is one of: + + ip -- IPPROTO_IP, Dummy protocol for TCP. + hopopts -- IPPROTO_HOPOPTS, IPv6 Hop-by-Hop options. + icmp -- IPPROTO_ICMP, Internet Control Message Protocol. + igmp -- IPPROTO_IGMP, Internet Group Management Protocol. + ipip -- IPPROTO_IPIP, IPIP tunnels (older KA9Q tunnels use 94). + tcp -- IPPROTO_TCP, Transmission Control Protocol. + egp -- IPPROTO_EGP, Exterior Gateway Protocol. + pup -- IPPROTO_PUP, PUP protocol. + udp -- IPPROTO_UDP, User Datagram Protocol. + idp -- IPPROTO_IDP, XNS IDP protocol. + tp -- IPPROTO_TP, SO Transport Protocol Class 4. + dccp -- IPPROTO_DCCP, Datagram Congestion Control Protocol. + ipv6 -- IPPROTO_IPV6, IPv6 header. + routing -- IPPROTO_ROUTING, IPv6 routing header. + fragment -- IPPROTO_FRAGMENT, IPv6 fragmentation header. + rsvp -- IPPROTO_RSVP, Reservation Protocol. + gre -- IPPROTO_GRE, General Routing Encapsulation. + esp -- IPPROTO_ESP, encapsulating security payload. + ah -- IPPROTO_AH, authentication header. + icmpv6 -- IPPROTO_ICMPV6, ICMPv6. + none -- IPPROTO_NONE, IPv6 no next header. + dstopts -- IPPROTO_DSTOPTS, IPv6 destination options. + mtp -- IPPROTO_MTP, Multicast Transport Protocol. + encap -- IPPROTO_ENCAP, Encapsulation Header. + pim -- IPPROTO_PIM, Protocol Independent Multicast. + comp -- IPPROTO_COMP, Compression Header Protocol. + sctp -- IPPROTO_SCTP, Stream Control Transmission Protocol. + udplite -- IPPROTO_UDPLITE, UDP-Lite protocol. + raw -- IPPROTO_RAW, Raw IP packets. + +Get returns the value as a string if it is known, or a number if it is not. + +Set returns the conntrack conntext, so calls can be chained. +*/ +static int get_attr_ipproto(lua_State* L) +{ + push_IPPROTO(L, + nfct_get_attr_u8(check_ct(L), check_attr(L))); + return 1; +} +static int set_attr_ipproto(lua_State* L) +{ + nfct_set_attr_u8( + check_ct(L), + check_attr(L), + check_IPPROTO(L,3)); + lua_settop(L, 1); + return 1; +} + +static int exp_new(lua_State* L) +{ + struct nf_expect* exp = nfexp_new(); + + if(!exp) { + return push_error(L); + } + + lua_pushlightuserdata(L, exp); + + lua_insert(L, 1); + + /* + * [1] exp + * [2] master + * [3] expected + * [4] mask + * [5] timeout + */ + switch(lua_gettop(L)) { + case 5: nfexp_set_attr_u32(exp, ATTR_EXP_TIMEOUT, luaL_checklong(L, 5)); + case 4: nfexp_set_attr(exp, ATTR_EXP_MASK, check_ct_argn(L, 4, "mask")); + case 3: nfexp_set_attr(exp, ATTR_EXP_EXPECTED, check_ct_argn(L, 3, "expected")); + case 2: nfexp_set_attr(exp, ATTR_EXP_MASTER, check_ct_argn(L, 2, "master")); + } + + lua_settop(L, 1); + + return 1; +} + +static int exp_destroy(lua_State* L) +{ + struct nf_expect* exp = check_exp(L, 1); + + nfexp_destroy(exp); + + return 0; +} + +/*- +-- cthandle = nfct.exp_query(cthandle, qtype, data) + +Currently, only create and destroy is supported. + + create -- NFCT_Q_CREATE, data must be an exp object + update -- NFCT_Q_UPDATE + destroy -- NFCT_Q_DESTROY, data must be an exp object + get -- NFCT_Q_GET + flush -- NFCT_Q_FLUSH + dump -- NFCT_Q_DUMP + dump-reset -- NFCT_Q_DUMP_RESET + create-update -- NFCT_Q_CREATE_UPDATE +*/ +static int exp_query(lua_State* L) +{ + struct nfct_handle* h = check_cthandle(L); + enum nf_conntrack_query qt = check_NFCT_Q(L, 2); + int eret; + + /* this api is hideous, the documentation of the types required is incomplete, and buried + deep + */ + switch(qt) { + case NFCT_Q_CREATE: + case NFCT_Q_DESTROY: + eret = nfexp_query(h, qt, check_exp(L, 3)); + break; + default: + return luaL_argerror(L, 2, "unsupported query type"); + } + + if(eret < 0) { + return push_error(L); + } + + lua_settop(L, 1); + + return 1; +} + + /*- -- h = nfct.ntohs(n) -- n = nfct.htons(h) @@ -799,23 +1134,38 @@ static const luaL_reg nfct[] = /* return or operate on ct */ {"new", new}, {"destroy", destroy}, - {"setobjopt", destroy}, + {"setobjopt", setobjopt}, {"get_attr_u8", get_attr_u8}, {"get_attr_u16", get_attr_u16}, {"get_attr_u32", get_attr_u32}, - {"get_attr_n16", get_attr_n16}, - {"get_attr_n32", get_attr_n32}, - {"get_attr_ipv4", get_attr_ipv4}, - {"get_attr_ipv6", get_attr_ipv6}, - {"get_attr_port", get_attr_n16}, {"set_attr_u8", set_attr_u8}, {"set_attr_u16", set_attr_u16}, {"set_attr_u32", set_attr_u32}, + + {"get_attr_n16", get_attr_n16}, + {"get_attr_n32", get_attr_n32}, {"set_attr_n16", set_attr_n16}, {"set_attr_n32", set_attr_n32}, + + /* TODO should probably use service names as strings */ + {"get_attr_port", get_attr_n16}, + {"set_attr_port", set_attr_n16}, + + {"get_attr_ipv4", get_attr_ipv4}, + {"get_attr_ipv6", get_attr_ipv6}, {"set_attr_ipv4", set_attr_ipv4}, {"set_attr_ipv6", set_attr_ipv6}, - {"set_attr_port", set_attr_n16}, + + {"get_attr_ipproto",get_attr_ipproto}, + {"set_attr_ipproto",set_attr_ipproto}, + + {"get_attr_pf", get_attr_pf}, + {"set_attr_pf", set_attr_pf}, + + /* return or operate on a exp */ + {"exp_new", exp_new}, + {"exp_destroy", exp_destroy}, + {"exp_query", exp_query}, /* attr value conversion */ {"ntohs", ctntohs}, diff --git a/lua/nflua.h b/lua/nflua.h index 0143930..1f37839 100644 --- a/lua/nflua.h +++ b/lua/nflua.h @@ -88,3 +88,271 @@ static int nfsetblocking(lua_State* L, int fd) return 1; } +#ifdef WANT_NF_LUA_PF +/*- +-- DOCUMENTATION + unspec -- PF_UNSPEC, Unspecified. + local -- PF_LOCAL, Local to host (pipes and file-domain). + unix -- PF_UNIX, POSIX name for PF_LOCAL. + file -- PF_FILE, Another non-standard name for PF_LOCAL. + inet -- PF_INET, IP protocol family. + ax25 -- PF_AX25, Amateur Radio AX.25. + ipx -- PF_IPX, Novell Internet Protocol. + appletalk -- PF_APPLETALK, Appletalk DDP. + netrom -- PF_NETROM, Amateur radio NetROM. + bridge -- PF_BRIDGE, Multiprotocol bridge. + atmpvc -- PF_ATMPVC, ATM PVCs. + x25 -- PF_X25, Reserved for X.25 project. + inet6 -- PF_INET6, IP version 6. + rose -- PF_ROSE, Amateur Radio X.25 PLP. + decnet -- PF_DECnet, Reserved for DECnet project. + netbeui -- PF_NETBEUI, Reserved for 802.2LLC project. + security -- PF_SECURITY, Security callback pseudo AF. + key -- PF_KEY, PF_KEY key management API. + netlink -- PF_NETLINK + route -- PF_ROUTE, Alias to emulate 4.4BSD. + packet -- PF_PACKET, Packet family. + ash -- PF_ASH, Ash. + econet -- PF_ECONET, Acorn Econet. + atmsvc -- PF_ATMSVC, ATM SVCs. + rds -- PF_RDS, RDS sockets. + sna -- PF_SNA, Linux SNA Project + irda -- PF_IRDA, IRDA sockets. + pppox -- PF_PPPOX, PPPoX sockets. + wanpipe -- PF_WANPIPE, Wanpipe API sockets. + llc -- PF_LLC, Linux LLC. + can -- PF_CAN, Controller Area Network. + tipc -- PF_TIPC, TIPC sockets. + bluetooth -- PF_BLUETOOTH, Bluetooth sockets. + iucv -- PF_IUCV, IUCV sockets. + rxrpc -- PF_RXRPC, RxRPC sockets. + isdn -- PF_ISDN, mISDN sockets. + phonet -- PF_PHONET, Phonet sockets. + ieee802154-- PF_IEEE802154, IEEE 802.15.4 sockets. +*/ +static const char* PF_opts[] = { + "unspec", + "local", + "unix", + "file", + "inet", + "ax25", + "ipx", + "appletalk", + "netrom", + "bridge", + "atmpvc", + "x25", + "inet6", + "rose", + "decnet", + "netbeui", + "security", + "key", + "netlink", + "route", + "packet", + "ash", + "econet", + "atmsvc", + "rds", + "sna", + "irda", + "pppox", + "wanpipe", + "llc", + "can", + "tipc", + "bluetooth", + "iucv", + "rxrpc", + "isdn", + "phonet", + "ieee802154", + NULL +}; + +static int PF_vals[] = { + PF_UNSPEC, + PF_LOCAL, + PF_UNIX, + PF_FILE, + PF_INET, + PF_AX25, + PF_IPX, + PF_APPLETALK, + PF_NETROM, + PF_BRIDGE, + PF_ATMPVC, + PF_X25, + PF_INET6, + PF_ROSE, + PF_DECnet, + PF_NETBEUI, + PF_SECURITY, + PF_KEY, + PF_NETLINK, + PF_ROUTE, + PF_PACKET, + PF_ASH, + PF_ECONET, + PF_ATMSVC, + PF_RDS, + PF_SNA, + PF_IRDA, + PF_PPPOX, + PF_WANPIPE, + PF_LLC, + PF_CAN, + PF_TIPC, + PF_BLUETOOTH, + PF_IUCV, + PF_RXRPC, + PF_ISDN, + PF_PHONET, + PF_IEEE802154, +}; + +static int check_PF(lua_State* L, int argn) +{ + int opt = luaL_checkoption(L, argn, NULL /* default? */, PF_opts); + int val = PF_vals[opt]; + return val; +} +#ifdef WANT_NF_LUA_PF_PUSH +static int PF_vals_size = 38; +static void push_PF(lua_State* L, int val) +{ + int i; + for(i = 0; i < PF_vals_size; i++) { + if(val == PF_vals[i]) { + lua_pushstring(L, PF_opts[i]); + return; + } + } + lua_pushnumber(L, val); + return; +} +#endif +#endif + +#ifdef WANT_NF_LUA_IPPROTO +/*- +-- DOCUMENTATION + ip -- IPPROTO_IP, Dummy protocol for TCP. + hopopts -- IPPROTO_HOPOPTS, IPv6 Hop-by-Hop options. + icmp -- IPPROTO_ICMP, Internet Control Message Protocol. + igmp -- IPPROTO_IGMP, Internet Group Management Protocol. + ipip -- IPPROTO_IPIP, IPIP tunnels (older KA9Q tunnels use 94). + tcp -- IPPROTO_TCP, Transmission Control Protocol. + egp -- IPPROTO_EGP, Exterior Gateway Protocol. + pup -- IPPROTO_PUP, PUP protocol. + udp -- IPPROTO_UDP, User Datagram Protocol. + idp -- IPPROTO_IDP, XNS IDP protocol. + tp -- IPPROTO_TP, SO Transport Protocol Class 4. + dccp -- IPPROTO_DCCP, Datagram Congestion Control Protocol. + ipv6 -- IPPROTO_IPV6, IPv6 header. + routing -- IPPROTO_ROUTING, IPv6 routing header. + fragment -- IPPROTO_FRAGMENT, IPv6 fragmentation header. + rsvp -- IPPROTO_RSVP, Reservation Protocol. + gre -- IPPROTO_GRE, General Routing Encapsulation. + esp -- IPPROTO_ESP, encapsulating security payload. + ah -- IPPROTO_AH, authentication header. + icmpv6 -- IPPROTO_ICMPV6, ICMPv6. + none -- IPPROTO_NONE, IPv6 no next header. + dstopts -- IPPROTO_DSTOPTS, IPv6 destination options. + mtp -- IPPROTO_MTP, Multicast Transport Protocol. + encap -- IPPROTO_ENCAP, Encapsulation Header. + pim -- IPPROTO_PIM, Protocol Independent Multicast. + comp -- IPPROTO_COMP, Compression Header Protocol. + sctp -- IPPROTO_SCTP, Stream Control Transmission Protocol. + udplite -- IPPROTO_UDPLITE, UDP-Lite protocol. + raw -- IPPROTO_RAW, Raw IP packets. +*/ +static const char* IPPROTO_opts[] = { + "ip", + "hopopts", + "icmp", + "igmp", + "ipip", + "tcp", + "egp", + "pup", + "udp", + "idp", + "tp", + "dccp", + "ipv6", + "routing", + "fragment", + "rsvp", + "gre", + "esp", + "ah", + "icmpv6", + "none", + "dstopts", + "mtp", + "encap", + "pim", + "comp", + "sctp", + "udplite", + "raw", + NULL +}; + +static int IPPROTO_vals[] = { + IPPROTO_IP, + IPPROTO_HOPOPTS, + IPPROTO_ICMP, + IPPROTO_IGMP, + IPPROTO_IPIP, + IPPROTO_TCP, + IPPROTO_EGP, + IPPROTO_PUP, + IPPROTO_UDP, + IPPROTO_IDP, + IPPROTO_TP, + IPPROTO_DCCP, + IPPROTO_IPV6, + IPPROTO_ROUTING, + IPPROTO_FRAGMENT, + IPPROTO_RSVP, + IPPROTO_GRE, + IPPROTO_ESP, + IPPROTO_AH, + IPPROTO_ICMPV6, + IPPROTO_NONE, + IPPROTO_DSTOPTS, + IPPROTO_MTP, + IPPROTO_ENCAP, + IPPROTO_PIM, + IPPROTO_COMP, + IPPROTO_SCTP, + IPPROTO_UDPLITE, + IPPROTO_RAW, +}; + +static int IPPROTO_vals_size = 29; +static int check_IPPROTO(lua_State* L, int argn) +{ + int opt = luaL_checkoption(L, argn, NULL /* default? */, IPPROTO_opts); + int val = IPPROTO_vals[opt]; + return val; +} + +static void push_IPPROTO(lua_State* L, int val) +{ + int i; + for(i = 0; i < IPPROTO_vals_size; i++) { + if(val == IPPROTO_vals[i]) { + lua_pushstring(L, IPPROTO_opts[i]); + return; + } + } + lua_pushnumber(L, val); + return; +} +#endif + diff --git a/lua/nfq.c b/lua/nfq.c index 82ca231..019ac13 100644 --- a/lua/nfq.c +++ b/lua/nfq.c @@ -46,6 +46,7 @@ replace input rule 1: sudo iptables -t filter -R INPUT 1 -p udp -j QUEUE */ +#define WANT_NF_LUA_PF #include "nflua.h" #include @@ -193,23 +194,6 @@ static int setblocking(lua_State* L) return nfsetblocking(L, nfq_fd(check_handle(L))); } -static int check_pf(lua_State* L, int narg) -{ - /* TODO ... other values from /usr/include/bits/socket.h */ - static const char* pf_opts[] = { - "inet", - "inet6", - NULL - }; - static int pf_vals[] = { - PF_INET, - PF_INET6, - }; - int pf_opt = luaL_checkoption(L, narg, NULL, pf_opts); - int pf_val = pf_vals[pf_opt]; - - return pf_val; -} /*- -- qhandle = nfq.unbind_pf(qhandle, family) @@ -221,7 +205,7 @@ Return is qhandle on success and nil,emsg,errno on failure. static int unbind_pf(lua_State* L) { struct nfq_handle* h = check_handle(L); - int pf = check_pf(L, 2); + int pf = check_PF(L, 2); if(nfq_unbind_pf(h, pf) < 0) { return push_error(L); @@ -246,7 +230,7 @@ Return is qhandle on success and nil,emsg,errno on failure. static int bind_pf(lua_State* L) { struct nfq_handle* h = check_handle(L); - int pf = check_pf(L, 2); + int pf = check_PF(L, 2); if(nfq_bind_pf(h, pf) < 0) { return push_error(L); -- cgit v1.2.1