summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
author/C=EU/ST=EU/CN=Pablo Neira Ayuso/emailAddress=pablo@netfilter.org </C=EU/ST=EU/CN=Pablo Neira Ayuso/emailAddress=pablo@netfilter.org>2008-02-09 20:01:39 +0000
committer/C=EU/ST=EU/CN=Pablo Neira Ayuso/emailAddress=pablo@netfilter.org </C=EU/ST=EU/CN=Pablo Neira Ayuso/emailAddress=pablo@netfilter.org>2008-02-09 20:01:39 +0000
commit7f9112dc9b40a7cb952d2d5927cae12cbb35960a (patch)
tree6a7cc48d9a62cfbb54e583c0a732003ff54ba615 /src
parentb2d40aaaff0feea0c682700c255d9e56b4980f0c (diff)
add support for NAT sequence adjusment
Diffstat (limited to 'src')
-rw-r--r--src/conntrack/build.c45
-rw-r--r--src/conntrack/getter.c36
-rw-r--r--src/conntrack/parse.c53
-rw-r--r--src/conntrack/setter.c36
4 files changed, 170 insertions, 0 deletions
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,
};