From 7f9112dc9b40a7cb952d2d5927cae12cbb35960a Mon Sep 17 00:00:00 2001 From: "/C=EU/ST=EU/CN=Pablo Neira Ayuso/emailAddress=pablo@netfilter.org" Date: Sat, 9 Feb 2008 20:01:39 +0000 Subject: add support for NAT sequence adjusment --- src/conntrack/build.c | 45 ++++++++++++++++++++++++++++++++++++++++++ src/conntrack/getter.c | 36 ++++++++++++++++++++++++++++++++++ src/conntrack/parse.c | 53 ++++++++++++++++++++++++++++++++++++++++++++++++++ src/conntrack/setter.c | 36 ++++++++++++++++++++++++++++++++++ 4 files changed, 170 insertions(+) (limited to 'src') diff --git a/src/conntrack/build.c b/src/conntrack/build.c index f5e7353..37dded0 100644 --- a/src/conntrack/build.c +++ b/src/conntrack/build.c @@ -117,6 +117,41 @@ void __build_protoinfo(struct nfnlhdr *req, } } +static inline void +__nat_seq_adj(struct nfnlhdr *req, + size_t size, + const struct nf_conntrack *ct, + int dir) +{ + nfnl_addattr32(&req->nlh, + size, + CTA_NAT_SEQ_CORRECTION_POS, + htonl(ct->tuple[dir].natseq.correction_pos)); + nfnl_addattr32(&req->nlh, + size, + CTA_NAT_SEQ_OFFSET_BEFORE, + htonl(ct->tuple[dir].natseq.offset_before)); + nfnl_addattr32(&req->nlh, + size, + CTA_NAT_SEQ_OFFSET_AFTER, + htonl(ct->tuple[dir].natseq.offset_after)); +} + +static void +__build_nat_seq_adj(struct nfnlhdr *req, + size_t size, + const struct nf_conntrack *ct, + int dir) +{ + struct nfattr *nest; + int type = (dir == __DIR_ORIG) ? CTA_NAT_SEQ_ADJ_ORIG : + CTA_NAT_SEQ_ADJ_REPLY; + + nest = nfnl_nest(&req->nlh, size, type); + __nat_seq_adj(req, size, ct, dir); + nfnl_nest_end(&req->nlh, nest); +} + void __build_protonat(struct nfnlhdr *req, size_t size, const struct nf_conntrack *ct, @@ -315,5 +350,15 @@ int __build_conntrack(struct nfnl_subsys_handle *ssh, else if (test_bit(ATTR_DNAT_PORT, ct->set)) __build_dnat_port(req, size, ct); + if (test_bit(ATTR_ORIG_NAT_SEQ_CORRECTION_POS, ct->set) && + test_bit(ATTR_ORIG_NAT_SEQ_OFFSET_BEFORE, ct->set) && + test_bit(ATTR_ORIG_NAT_SEQ_OFFSET_AFTER, ct->set)) + __build_nat_seq_adj(req, size, ct, __DIR_ORIG); + + if (test_bit(ATTR_REPL_NAT_SEQ_CORRECTION_POS, ct->set) && + test_bit(ATTR_REPL_NAT_SEQ_OFFSET_BEFORE, ct->set) && + test_bit(ATTR_REPL_NAT_SEQ_OFFSET_AFTER, ct->set)) + __build_nat_seq_adj(req, size, ct, __DIR_REPL); + return 0; } diff --git a/src/conntrack/getter.c b/src/conntrack/getter.c index 184eac4..e887ee4 100644 --- a/src/conntrack/getter.c +++ b/src/conntrack/getter.c @@ -192,6 +192,36 @@ static const void *get_attr_use(const struct nf_conntrack *ct) return &ct->use; } +static const void *get_attr_orig_cor_pos(const struct nf_conntrack *ct) +{ + return &ct->tuple[__DIR_ORIG].natseq.correction_pos; +} + +static const void *get_attr_orig_off_bfr(const struct nf_conntrack *ct) +{ + return &ct->tuple[__DIR_ORIG].natseq.offset_before; +} + +static const void *get_attr_orig_off_aft(const struct nf_conntrack *ct) +{ + return &ct->tuple[__DIR_ORIG].natseq.offset_after; +} + +static const void *get_attr_repl_cor_pos(const struct nf_conntrack *ct) +{ + return &ct->tuple[__DIR_REPL].natseq.correction_pos; +} + +static const void *get_attr_repl_off_bfr(const struct nf_conntrack *ct) +{ + return &ct->tuple[__DIR_REPL].natseq.offset_before; +} + +static const void *get_attr_repl_off_aft(const struct nf_conntrack *ct) +{ + return &ct->tuple[__DIR_REPL].natseq.offset_after; +} + get_attr get_attr_array[] = { [ATTR_ORIG_IPV4_SRC] = get_attr_orig_ipv4_src, [ATTR_ORIG_IPV4_DST] = get_attr_orig_ipv4_dst, @@ -230,4 +260,10 @@ get_attr get_attr_array[] = { [ATTR_TCP_MASK_ORIG] = get_attr_tcp_mask_orig, [ATTR_TCP_MASK_REPL] = get_attr_tcp_mask_repl, [ATTR_SECMARK] = get_attr_secmark, + [ATTR_ORIG_NAT_SEQ_CORRECTION_POS] = get_attr_orig_cor_pos, + [ATTR_ORIG_NAT_SEQ_OFFSET_BEFORE] = get_attr_orig_off_bfr, + [ATTR_ORIG_NAT_SEQ_OFFSET_AFTER] = get_attr_orig_off_aft, + [ATTR_REPL_NAT_SEQ_CORRECTION_POS] = get_attr_repl_cor_pos, + [ATTR_REPL_NAT_SEQ_OFFSET_BEFORE] = get_attr_repl_off_bfr, + [ATTR_REPL_NAT_SEQ_OFFSET_AFTER] = get_attr_repl_off_aft, }; diff --git a/src/conntrack/parse.c b/src/conntrack/parse.c index d5482cc..6fc7732 100644 --- a/src/conntrack/parse.c +++ b/src/conntrack/parse.c @@ -263,6 +263,53 @@ static void __parse_counters(const struct nfattr *attr, } } +static void +__parse_nat_seq(const struct nfattr *attr, struct nf_conntrack *ct, int dir) +{ + struct nfattr *tb[CTA_NAT_SEQ_MAX]; + + nfnl_parse_nested(tb, CTA_NAT_SEQ_MAX, attr); + + if (tb[CTA_NAT_SEQ_CORRECTION_POS-1]) { + ct->tuple[dir].natseq.correction_pos = + ntohl(*(u_int32_t *)NFA_DATA(tb[CTA_NAT_SEQ_CORRECTION_POS-1])); + switch(dir) { + case __DIR_ORIG: + set_bit(ATTR_ORIG_NAT_SEQ_CORRECTION_POS, ct->set); + break; + case __DIR_REPL: + set_bit(ATTR_REPL_NAT_SEQ_CORRECTION_POS, ct->set); + break; + } + } + + if (tb[CTA_NAT_SEQ_OFFSET_BEFORE-1]) { + ct->tuple[dir].natseq.offset_before = + ntohl(*(u_int32_t *)NFA_DATA(tb[CTA_NAT_SEQ_OFFSET_BEFORE-1])); + switch(dir) { + case __DIR_ORIG: + set_bit(ATTR_ORIG_NAT_SEQ_OFFSET_BEFORE, ct->set); + break; + case __DIR_REPL: + set_bit(ATTR_REPL_NAT_SEQ_OFFSET_BEFORE, ct->set); + break; + } + } + + if (tb[CTA_NAT_SEQ_OFFSET_AFTER-1]) { + ct->tuple[dir].natseq.offset_after = + ntohl(*(u_int32_t *)NFA_DATA(tb[CTA_NAT_SEQ_OFFSET_AFTER-1])); + switch(dir) { + case __DIR_ORIG: + set_bit(ATTR_ORIG_NAT_SEQ_OFFSET_AFTER, ct->set); + break; + case __DIR_REPL: + set_bit(ATTR_REPL_NAT_SEQ_OFFSET_AFTER, ct->set); + break; + } + } +} + int __parse_message_type(const struct nlmsghdr *nlh) { u_int16_t type = NFNL_MSG_TYPE(nlh->nlmsg_type); @@ -304,6 +351,12 @@ void __parse_conntrack(const struct nlmsghdr *nlh, __parse_tuple(cda[CTA_TUPLE_MASTER-1], &ct->tuple[__DIR_MASTER], __DIR_MASTER, ct->set); + if (cda[CTA_NAT_SEQ_ADJ_ORIG-1]) + __parse_nat_seq(cda[CTA_NAT_SEQ_ADJ_ORIG-1], ct, __DIR_ORIG); + + if (cda[CTA_NAT_SEQ_ADJ_REPLY-1]) + __parse_nat_seq(cda[CTA_NAT_SEQ_ADJ_REPLY-1], ct, __DIR_REPL); + if (cda[CTA_STATUS-1]) { ct->status = ntohl(*(u_int32_t *)NFA_DATA(cda[CTA_STATUS-1])); set_bit(ATTR_STATUS, ct->set); diff --git a/src/conntrack/setter.c b/src/conntrack/setter.c index 39f0396..5ba8e40 100644 --- a/src/conntrack/setter.c +++ b/src/conntrack/setter.c @@ -207,6 +207,36 @@ static void set_attr_master_l4proto(struct nf_conntrack *ct, const void *value) ct->tuple[__DIR_MASTER].protonum = *((u_int8_t *) value); } +static void set_attr_orig_cor_pos(struct nf_conntrack *ct, const void *value) +{ + ct->tuple[__DIR_ORIG].natseq.correction_pos = *((u_int32_t *) value); +} + +static void set_attr_orig_off_bfr(struct nf_conntrack *ct, const void *value) +{ + ct->tuple[__DIR_ORIG].natseq.offset_before = *((u_int32_t *) value); +} + +static void set_attr_orig_off_aft(struct nf_conntrack *ct, const void *value) +{ + ct->tuple[__DIR_ORIG].natseq.offset_after = *((u_int32_t *) value); +} + +static void set_attr_repl_cor_pos(struct nf_conntrack *ct, const void *value) +{ + ct->tuple[__DIR_REPL].natseq.correction_pos = *((u_int32_t *) value); +} + +static void set_attr_repl_off_bfr(struct nf_conntrack *ct, const void *value) +{ + ct->tuple[__DIR_REPL].natseq.offset_before = *((u_int32_t *) value); +} + +static void set_attr_repl_off_aft(struct nf_conntrack *ct, const void *value) +{ + ct->tuple[__DIR_REPL].natseq.offset_after = *((u_int32_t *) value); +} + set_attr set_attr_array[] = { [ATTR_ORIG_IPV4_SRC] = set_attr_orig_ipv4_src, [ATTR_ORIG_IPV4_DST] = set_attr_orig_ipv4_dst, @@ -248,4 +278,10 @@ set_attr set_attr_array[] = { [ATTR_MASTER_L3PROTO] = set_attr_master_l3proto, [ATTR_MASTER_L4PROTO] = set_attr_master_l4proto, [ATTR_SECMARK] = set_attr_secmark, + [ATTR_ORIG_NAT_SEQ_CORRECTION_POS] = set_attr_orig_cor_pos, + [ATTR_ORIG_NAT_SEQ_OFFSET_BEFORE] = set_attr_orig_off_aft, + [ATTR_ORIG_NAT_SEQ_OFFSET_AFTER] = set_attr_orig_off_bfr, + [ATTR_REPL_NAT_SEQ_CORRECTION_POS] = set_attr_repl_cor_pos, + [ATTR_REPL_NAT_SEQ_OFFSET_BEFORE] = set_attr_repl_off_aft, + [ATTR_REPL_NAT_SEQ_OFFSET_AFTER] = set_attr_repl_off_bfr, }; -- cgit v1.2.3