summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPablo Neira Ayuso <pablo@netfilter.org>2018-03-13 18:44:11 +0100
committerPablo Neira Ayuso <pablo@netfilter.org>2018-03-24 21:37:32 +0100
commit2edc7ccd872c60f4a71218e34e737655d6e50efa (patch)
tree4294844e1e3f7b81f907f618ea09943552878b09
parente870432649955d377a73ee5a72cb23f0f6b5e4c5 (diff)
conntrack: add synproxy support
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
-rw-r--r--include/internal/object.h6
-rw-r--r--include/libnetfilter_conntrack/libnetfilter_conntrack.h3
-rw-r--r--include/libnetfilter_conntrack/linux_nfnetlink_conntrack.h10
-rw-r--r--src/conntrack/build.c20
-rw-r--r--src/conntrack/build_mnl.c17
-rw-r--r--src/conntrack/copy.c21
-rw-r--r--src/conntrack/getter.c18
-rw-r--r--src/conntrack/parse.c28
-rw-r--r--src/conntrack/parse_mnl.c54
-rw-r--r--src/conntrack/setter.c21
10 files changed, 198 insertions, 0 deletions
diff --git a/include/internal/object.h b/include/internal/object.h
index bb14dc8..3f6904f 100644
--- a/include/internal/object.h
+++ b/include/internal/object.h
@@ -189,6 +189,12 @@ struct nf_conntrack {
uint64_t stop;
} timestamp;
+ struct {
+ uint32_t isn;
+ uint32_t its;
+ uint32_t tsoff;
+ } synproxy;
+
void *helper_info;
size_t helper_info_len;
diff --git a/include/libnetfilter_conntrack/libnetfilter_conntrack.h b/include/libnetfilter_conntrack/libnetfilter_conntrack.h
index b8d458c..c5c6b61 100644
--- a/include/libnetfilter_conntrack/libnetfilter_conntrack.h
+++ b/include/libnetfilter_conntrack/libnetfilter_conntrack.h
@@ -141,6 +141,9 @@ enum nf_conntrack_attr {
ATTR_REPL_ZONE, /* u16 bits */
ATTR_SNAT_IPV6, /* u128 bits */
ATTR_DNAT_IPV6, /* u128 bits */
+ ATTR_SYNPROXY_ISN, /* u32 bits */
+ ATTR_SYNPROXY_ITS, /* u32 bits */
+ ATTR_SYNPROXY_TSOFF, /* u32 bits */
ATTR_MAX
};
diff --git a/include/libnetfilter_conntrack/linux_nfnetlink_conntrack.h b/include/libnetfilter_conntrack/linux_nfnetlink_conntrack.h
index f1f50b7..aa45723 100644
--- a/include/libnetfilter_conntrack/linux_nfnetlink_conntrack.h
+++ b/include/libnetfilter_conntrack/linux_nfnetlink_conntrack.h
@@ -57,6 +57,7 @@ enum ctattr_type {
CTA_MARK_MASK,
CTA_LABELS,
CTA_LABELS_MASK,
+ CTA_SYNPROXY,
__CTA_MAX
};
#define CTA_MAX (__CTA_MAX - 1)
@@ -190,6 +191,15 @@ enum ctattr_natseq {
};
#define CTA_NAT_SEQ_MAX (__CTA_NAT_SEQ_MAX - 1)
+enum ctattr_synproxy {
+ CTA_SYNPROXY_UNSPEC,
+ CTA_SYNPROXY_ISN,
+ CTA_SYNPROXY_ITS,
+ CTA_SYNPROXY_TSOFF,
+ __CTA_SYNPROXY_MAX,
+};
+#define CTA_SYNPROXY_MAX (__CTA_SYNPROXY_MAX - 1)
+
enum ctattr_expect {
CTA_EXPECT_UNSPEC,
CTA_EXPECT_MASTER,
diff --git a/src/conntrack/build.c b/src/conntrack/build.c
index cf282e6..d132890 100644
--- a/src/conntrack/build.c
+++ b/src/conntrack/build.c
@@ -459,6 +459,21 @@ static void __build_labels(struct nfnlhdr *req,
}
}
+static void __build_synproxy(struct nfnlhdr *req, size_t size,
+ const struct nf_conntrack *ct)
+{
+ struct nfattr *nest;
+
+ nest = nfnl_nest(&req->nlh, size, CTA_SYNPROXY);
+ nfnl_addattr32(&req->nlh, size, CTA_SYNPROXY_ISN,
+ htonl(ct->synproxy.isn));
+ nfnl_addattr32(&req->nlh, size, CTA_SYNPROXY_ITS,
+ htonl(ct->synproxy.its));
+ nfnl_addattr32(&req->nlh, size, CTA_SYNPROXY_TSOFF,
+ htonl(ct->synproxy.tsoff));
+ nfnl_nest_end(&req->nlh, nest);
+}
+
int __build_conntrack(struct nfnl_subsys_handle *ssh,
struct nfnlhdr *req,
size_t size,
@@ -594,5 +609,10 @@ int __build_conntrack(struct nfnl_subsys_handle *ssh,
if (test_bit(ATTR_CONNLABELS, ct->head.set))
__build_labels(req, size, ct);
+ if (test_bit(ATTR_SYNPROXY_ISN, ct->head.set) &&
+ test_bit(ATTR_SYNPROXY_ITS, ct->head.set) &&
+ test_bit(ATTR_SYNPROXY_TSOFF, ct->head.set))
+ __build_synproxy(req, size, ct);
+
return 0;
}
diff --git a/src/conntrack/build_mnl.c b/src/conntrack/build_mnl.c
index 2118bf3..d9ad268 100644
--- a/src/conntrack/build_mnl.c
+++ b/src/conntrack/build_mnl.c
@@ -438,6 +438,18 @@ nfct_build_labels(struct nlmsghdr *nlh, const struct nf_conntrack *ct)
}
}
+static void nfct_build_synproxy(struct nlmsghdr *nlh,
+ const struct nf_conntrack *ct)
+{
+ struct nlattr *nest;
+
+ nest = mnl_attr_nest_start(nlh, CTA_SYNPROXY);
+ mnl_attr_put_u32(nlh, CTA_SYNPROXY_ISN, htonl(ct->synproxy.isn));
+ mnl_attr_put_u32(nlh, CTA_SYNPROXY_ITS, htonl(ct->synproxy.its));
+ mnl_attr_put_u32(nlh, CTA_SYNPROXY_TSOFF, htonl(ct->synproxy.tsoff));
+ mnl_attr_nest_end(nlh, nest);
+}
+
int
nfct_nlmsg_build(struct nlmsghdr *nlh, const struct nf_conntrack *ct)
{
@@ -579,5 +591,10 @@ nfct_nlmsg_build(struct nlmsghdr *nlh, const struct nf_conntrack *ct)
if (test_bit(ATTR_CONNLABELS, ct->head.set))
nfct_build_labels(nlh, ct);
+ if (test_bit(ATTR_SYNPROXY_ISN, ct->head.set) &&
+ test_bit(ATTR_SYNPROXY_ITS, ct->head.set) &&
+ test_bit(ATTR_SYNPROXY_TSOFF, ct->head.set))
+ nfct_build_synproxy(nlh, ct);
+
return 0;
}
diff --git a/src/conntrack/copy.c b/src/conntrack/copy.c
index e6e4f7a..eca202e 100644
--- a/src/conntrack/copy.c
+++ b/src/conntrack/copy.c
@@ -498,6 +498,24 @@ static void copy_attr_connlabels_mask(struct nf_conntrack *dest,
dest->connlabels_mask = do_copy_attr_connlabels(dest->connlabels_mask, orig->connlabels_mask);
}
+static void copy_attr_synproxy_its(struct nf_conntrack *dest,
+ const struct nf_conntrack *orig)
+{
+ dest->synproxy.its = orig->synproxy.its;
+}
+
+static void copy_attr_synproxy_isn(struct nf_conntrack *dest,
+ const struct nf_conntrack *orig)
+{
+ dest->synproxy.isn = orig->synproxy.isn;
+}
+
+static void copy_attr_synproxy_tsoff(struct nf_conntrack *dest,
+ const struct nf_conntrack *orig)
+{
+ dest->synproxy.tsoff = orig->synproxy.tsoff;
+}
+
const copy_attr copy_attr_array[ATTR_MAX] = {
[ATTR_ORIG_IPV4_SRC] = copy_attr_orig_ipv4_src,
[ATTR_ORIG_IPV4_DST] = copy_attr_orig_ipv4_dst,
@@ -571,6 +589,9 @@ const copy_attr copy_attr_array[ATTR_MAX] = {
[ATTR_CONNLABELS_MASK] = copy_attr_connlabels_mask,
[ATTR_SNAT_IPV6] = copy_attr_snat_ipv6,
[ATTR_DNAT_IPV6] = copy_attr_dnat_ipv6,
+ [ATTR_SYNPROXY_ITS] = copy_attr_synproxy_its,
+ [ATTR_SYNPROXY_ISN] = copy_attr_synproxy_isn,
+ [ATTR_SYNPROXY_TSOFF] = copy_attr_synproxy_tsoff,
};
/* this is used by nfct_copy() with the NFCT_CP_OVERRIDE flag set. */
diff --git a/src/conntrack/getter.c b/src/conntrack/getter.c
index e818a05..d1f9a5a 100644
--- a/src/conntrack/getter.c
+++ b/src/conntrack/getter.c
@@ -369,6 +369,21 @@ static const void *get_attr_connlabels_mask(const struct nf_conntrack *ct)
return ct->connlabels_mask;
}
+static const void *get_attr_synproxy_isn(const struct nf_conntrack *ct)
+{
+ return &ct->synproxy.isn;
+}
+
+static const void *get_attr_synproxy_its(const struct nf_conntrack *ct)
+{
+ return &ct->synproxy.its;
+}
+
+static const void *get_attr_synproxy_tsoff(const struct nf_conntrack *ct)
+{
+ return &ct->synproxy.tsoff;
+}
+
const get_attr get_attr_array[ATTR_MAX] = {
[ATTR_ORIG_IPV4_SRC] = get_attr_orig_ipv4_src,
[ATTR_ORIG_IPV4_DST] = get_attr_orig_ipv4_dst,
@@ -442,4 +457,7 @@ const get_attr get_attr_array[ATTR_MAX] = {
[ATTR_CONNLABELS_MASK] = get_attr_connlabels_mask,
[ATTR_SNAT_IPV6] = get_attr_snat_ipv6,
[ATTR_DNAT_IPV6] = get_attr_dnat_ipv6,
+ [ATTR_SYNPROXY_ISN] = get_attr_synproxy_isn,
+ [ATTR_SYNPROXY_ITS] = get_attr_synproxy_its,
+ [ATTR_SYNPROXY_TSOFF] = get_attr_synproxy_tsoff,
};
diff --git a/src/conntrack/parse.c b/src/conntrack/parse.c
index b52454b..8c1d813 100644
--- a/src/conntrack/parse.c
+++ b/src/conntrack/parse.c
@@ -422,6 +422,31 @@ __parse_nat_seq(const struct nfattr *attr, struct nf_conntrack *ct, int dir)
}
}
+static void __parse_synproxy(const struct nfattr *attr, struct nf_conntrack *ct)
+{
+ struct nfattr *tb[CTA_SYNPROXY_MAX];
+
+ nfnl_parse_nested(tb, CTA_SYNPROXY_MAX, attr);
+
+ if (tb[CTA_SYNPROXY_ISN - 1]) {
+ ct->synproxy.isn =
+ ntohl(*(uint32_t *)NFA_DATA(tb[CTA_SYNPROXY_ISN-1]));
+ set_bit(ATTR_SYNPROXY_ISN, ct->head.set);
+ }
+
+ if (tb[CTA_SYNPROXY_ITS - 1]) {
+ ct->synproxy.its =
+ ntohl(*(uint32_t *)NFA_DATA(tb[CTA_SYNPROXY_ITS-1]));
+ set_bit(ATTR_SYNPROXY_ITS, ct->head.set);
+ }
+
+ if (tb[CTA_SYNPROXY_TSOFF - 1]) {
+ ct->synproxy.tsoff =
+ ntohl(*(uint32_t *)NFA_DATA(tb[CTA_SYNPROXY_TSOFF-1]));
+ set_bit(ATTR_SYNPROXY_TSOFF, ct->head.set);
+ }
+}
+
static void
__parse_helper(const struct nfattr *attr, struct nf_conntrack *ct)
{
@@ -596,4 +621,7 @@ void __parse_conntrack(const struct nlmsghdr *nlh,
if (cda[CTA_LABELS-1])
__parse_labels(cda[CTA_LABELS-1], ct);
+
+ if (cda[CTA_SYNPROXY-1])
+ __parse_synproxy(cda[CTA_SYNPROXY-1], ct);
}
diff --git a/src/conntrack/parse_mnl.c b/src/conntrack/parse_mnl.c
index 56a575e..94a0de7 100644
--- a/src/conntrack/parse_mnl.c
+++ b/src/conntrack/parse_mnl.c
@@ -809,6 +809,55 @@ static int nfct_parse_labels(const struct nlattr *attr, struct nf_conntrack *ct)
return 0;
}
+static int nfct_parse_synproxy_attr_cb(const struct nlattr *attr, void *data)
+{
+ int type = mnl_attr_get_type(attr);
+ const struct nlattr **tb = data;
+
+ if (mnl_attr_type_valid(attr, CTA_SYNPROXY_MAX) < 0)
+ return MNL_CB_OK;
+
+ switch(type) {
+ case CTA_SYNPROXY_ISN:
+ case CTA_SYNPROXY_ITS:
+ case CTA_SYNPROXY_TSOFF:
+ if (mnl_attr_validate(attr, MNL_TYPE_U32) < 0)
+ return MNL_CB_ERROR;
+ break;
+ }
+ tb[type] = attr;
+ return MNL_CB_OK;
+}
+
+static int nfct_parse_synproxy(const struct nlattr *attr,
+ struct nf_conntrack *ct)
+{
+ struct nlattr *tb[CTA_SYNPROXY + 1] = {};
+
+ if (mnl_attr_parse_nested(attr, nfct_parse_synproxy_attr_cb, tb) < 0)
+ return -1;
+
+ if (tb[CTA_SYNPROXY_ISN]) {
+ ct->synproxy.isn =
+ ntohl(mnl_attr_get_u32(tb[CTA_SYNPROXY_ISN]));
+ set_bit(ATTR_SYNPROXY_ISN, ct->head.set);
+ }
+
+ if (tb[CTA_SYNPROXY_ITS]) {
+ ct->synproxy.its =
+ ntohl(mnl_attr_get_u32(tb[CTA_SYNPROXY_ITS]));
+ set_bit(ATTR_SYNPROXY_ITS, ct->head.set);
+ }
+
+ if (tb[CTA_SYNPROXY_TSOFF]) {
+ ct->synproxy.tsoff =
+ ntohl(mnl_attr_get_u32(tb[CTA_SYNPROXY_TSOFF]));
+ set_bit(ATTR_SYNPROXY_TSOFF, ct->head.set);
+ }
+
+ return 0;
+}
+
static int
nfct_parse_conntrack_attr_cb(const struct nlattr *attr, void *data)
{
@@ -977,6 +1026,11 @@ nfct_payload_parse(const void *payload, size_t payload_len,
}
/* CTA_LABELS_MASK: never sent by kernel */
+ if (tb[CTA_SYNPROXY]) {
+ if (nfct_parse_synproxy(tb[CTA_SYNPROXY], ct) < 0)
+ return -1;
+ }
+
return 0;
}
diff --git a/src/conntrack/setter.c b/src/conntrack/setter.c
index 75ab09e..7b96936 100644
--- a/src/conntrack/setter.c
+++ b/src/conntrack/setter.c
@@ -468,6 +468,24 @@ set_attr_connlabels_mask(struct nf_conntrack *ct, const void *value, size_t len)
}
static void
+set_attr_synproxy_isn(struct nf_conntrack *ct, const void *value, size_t len)
+{
+ ct->synproxy.isn = *((uint32_t *) value);
+}
+
+static void
+set_attr_synproxy_its(struct nf_conntrack *ct, const void *value, size_t len)
+{
+ ct->synproxy.its = *((uint32_t *) value);
+}
+
+static void
+set_attr_synproxy_tsoff(struct nf_conntrack *ct, const void *value, size_t len)
+{
+ ct->synproxy.tsoff = *((uint32_t *) value);
+}
+
+static void
set_attr_do_nothing(struct nf_conntrack *ct, const void *value, size_t len) {}
const set_attr set_attr_array[ATTR_MAX] = {
@@ -543,4 +561,7 @@ const set_attr set_attr_array[ATTR_MAX] = {
[ATTR_CONNLABELS_MASK] = set_attr_connlabels_mask,
[ATTR_SNAT_IPV6] = set_attr_snat_ipv6,
[ATTR_DNAT_IPV6] = set_attr_dnat_ipv6,
+ [ATTR_SYNPROXY_ISN] = set_attr_synproxy_isn,
+ [ATTR_SYNPROXY_ITS] = set_attr_synproxy_its,
+ [ATTR_SYNPROXY_TSOFF] = set_attr_synproxy_tsoff,
};