From 7dd5289076160ee2844978bfd1640ca7aa34f4da Mon Sep 17 00:00:00 2001 From: Pablo Neira Ayuso Date: Thu, 30 Oct 2008 20:44:25 +0100 Subject: groups: add attribute group API This new API allows you to set and get some logical set of attributes. This is not intended to replace the existing per-attribute get/set API but to provide more efficient way to get/set certain attributes. This change includes an example file (conntrack_grp_create.c) of the use of the attribute group API. See ATTR_GRP_* for more information on the existing groups. Signed-off-by: Pablo Neira Ayuso --- src/conntrack/grp_setter.c | 156 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 156 insertions(+) create mode 100644 src/conntrack/grp_setter.c (limited to 'src/conntrack/grp_setter.c') diff --git a/src/conntrack/grp_setter.c b/src/conntrack/grp_setter.c new file mode 100644 index 0000000..16f0a10 --- /dev/null +++ b/src/conntrack/grp_setter.c @@ -0,0 +1,156 @@ +/* + * (C) 2008 by Pablo Neira Ayuso + * + * This software may be used and distributed according to the terms + * of the GNU General Public License, incorporated herein by reference. + */ + +#include "internal/internal.h" +#include +#include + +static const u_int8_t invmap_icmp[] = { + [ICMP_ECHO] = ICMP_ECHOREPLY + 1, + [ICMP_ECHOREPLY] = ICMP_ECHO + 1, + [ICMP_TIMESTAMP] = ICMP_TIMESTAMPREPLY + 1, + [ICMP_TIMESTAMPREPLY] = ICMP_TIMESTAMP + 1, + [ICMP_INFO_REQUEST] = ICMP_INFO_REPLY + 1, + [ICMP_INFO_REPLY] = ICMP_INFO_REQUEST + 1, + [ICMP_ADDRESS] = ICMP_ADDRESSREPLY + 1, + [ICMP_ADDRESSREPLY] = ICMP_ADDRESS + 1 +}; + +#ifndef ICMPV6_NI_QUERY +#define ICMPV6_NI_QUERY 139 +#endif + +#ifndef ICMPV6_NI_REPLY +#define ICMPV6_NI_REPLY 140 +#endif + +static u_int8_t invmap_icmpv6[] = { + [ICMPV6_ECHO_REQUEST - 128] = ICMPV6_ECHO_REPLY + 1, + [ICMPV6_ECHO_REPLY - 128] = ICMPV6_ECHO_REQUEST + 1, + [ICMPV6_NI_QUERY - 128] = ICMPV6_NI_QUERY + 1, + [ICMPV6_NI_REPLY - 128] = ICMPV6_NI_REPLY + 1 +}; + +static void set_attr_grp_orig_ipv4(struct nf_conntrack *ct, const void *value) +{ + const struct nfct_attr_grp_ipv4 *this = value; + ct->tuple[__DIR_ORIG].src.v4 = this->src; + ct->tuple[__DIR_ORIG].dst.v4 = this->dst; + ct->tuple[__DIR_ORIG].l3protonum = AF_INET; +} + +static void set_attr_grp_repl_ipv4(struct nf_conntrack *ct, const void *value) +{ + const struct nfct_attr_grp_ipv4 *this = value; + ct->tuple[__DIR_REPL].src.v4 = this->src; + ct->tuple[__DIR_REPL].dst.v4 = this->dst; + ct->tuple[__DIR_REPL].l3protonum = AF_INET; +} + +static void set_attr_grp_orig_ipv6(struct nf_conntrack *ct, const void *value) +{ + const struct nfct_attr_grp_ipv6 *this = value; + memcpy(&ct->tuple[__DIR_ORIG].src.v6, this->src, sizeof(u_int32_t)*4); + memcpy(&ct->tuple[__DIR_ORIG].dst.v6, this->dst, sizeof(u_int32_t)*4); + ct->tuple[__DIR_ORIG].l3protonum = AF_INET6; +} + +static void set_attr_grp_repl_ipv6(struct nf_conntrack *ct, const void *value) +{ + const struct nfct_attr_grp_ipv6 *this = value; + memcpy(&ct->tuple[__DIR_REPL].src.v6, this->src, sizeof(u_int32_t)*4); + memcpy(&ct->tuple[__DIR_REPL].dst.v6, this->dst, sizeof(u_int32_t)*4); + ct->tuple[__DIR_REPL].l3protonum = AF_INET6; +} + +static void set_attr_grp_orig_port(struct nf_conntrack *ct, const void *value) +{ + const struct nfct_attr_grp_port *this = value; + ct->tuple[__DIR_ORIG].l4src.all = this->sport; + ct->tuple[__DIR_ORIG].l4dst.all = this->dport; +} + +static void set_attr_grp_repl_port(struct nf_conntrack *ct, const void *value) +{ + const struct nfct_attr_grp_port *this = value; + ct->tuple[__DIR_REPL].l4src.all = this->sport; + ct->tuple[__DIR_REPL].l4dst.all = this->dport; +} + +static void set_attr_grp_icmp(struct nf_conntrack *ct, const void *value) +{ + u_int8_t rtype; + const struct nfct_attr_grp_icmp *this = value; + + ct->tuple[__DIR_ORIG].l4dst.icmp.type = this->type; + + switch(ct->tuple[__DIR_ORIG].l3protonum) { + case AF_INET: + rtype = invmap_icmp[this->type]; + break; + + case AF_INET6: + rtype = invmap_icmpv6[this->type - 128]; + break; + + default: + rtype = 0; /* not found */ + } + + if (rtype) + ct->tuple[__DIR_REPL].l4dst.icmp.type = rtype - 1; + else + ct->tuple[__DIR_REPL].l4dst.icmp.type = 255; /* -EINVAL */ + + ct->tuple[__DIR_ORIG].l4dst.icmp.code = this->code; + ct->tuple[__DIR_REPL].l4dst.icmp.code = this->code; + + ct->tuple[__DIR_ORIG].l4src.icmp.id = this->id; + ct->tuple[__DIR_REPL].l4src.icmp.id = this->id; +} + +static void set_attr_grp_master_ipv4(struct nf_conntrack *ct, const void *value) +{ + const struct nfct_attr_grp_ipv4 *this = value; + ct->tuple[__DIR_MASTER].src.v4 = this->src; + ct->tuple[__DIR_MASTER].dst.v4 = this->dst; + ct->tuple[__DIR_MASTER].l3protonum = AF_INET; +} + +static void set_attr_grp_master_ipv6(struct nf_conntrack *ct, const void *value) +{ + const struct nfct_attr_grp_ipv6 *this = value; + memcpy(&ct->tuple[__DIR_MASTER].src.v6, this->src, sizeof(u_int32_t)*4); + memcpy(&ct->tuple[__DIR_MASTER].dst.v6, this->dst, sizeof(u_int32_t)*4); + ct->tuple[__DIR_MASTER].l3protonum = AF_INET6; +} + +static void set_attr_grp_master_port(struct nf_conntrack *ct, const void *value) +{ + const struct nfct_attr_grp_port *this = value; + ct->tuple[__DIR_MASTER].l4src.all = this->sport; + ct->tuple[__DIR_MASTER].l4dst.all = this->dport; +} + +static void set_attr_grp_do_nothing(struct nf_conntrack *ct, const void *value) +{ +} + +set_attr_grp set_attr_grp_array[] = { + [ATTR_GRP_ORIG_IPV4] = set_attr_grp_orig_ipv4, + [ATTR_GRP_REPL_IPV4] = set_attr_grp_repl_ipv4, + [ATTR_GRP_ORIG_IPV6] = set_attr_grp_orig_ipv6, + [ATTR_GRP_REPL_IPV6] = set_attr_grp_repl_ipv6, + [ATTR_GRP_ORIG_PORT] = set_attr_grp_orig_port, + [ATTR_GRP_REPL_PORT] = set_attr_grp_repl_port, + [ATTR_GRP_ICMP] = set_attr_grp_icmp, + [ATTR_GRP_MASTER_IPV4] = set_attr_grp_master_ipv4, + [ATTR_GRP_MASTER_IPV6] = set_attr_grp_master_ipv6, + [ATTR_GRP_MASTER_PORT] = set_attr_grp_master_port, + [ATTR_GRP_ORIG_COUNTERS] = set_attr_grp_do_nothing, + [ATTR_GRP_REPL_COUNTERS] = set_attr_grp_do_nothing, +}; -- cgit v1.2.3