summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--configure.in2
-rw-r--r--include/internal.h12
-rw-r--r--include/libnetfilter_conntrack/libnetfilter_conntrack.h20
-rw-r--r--include/libnetfilter_conntrack/linux_nfnetlink_conntrack.h4
-rw-r--r--src/conntrack/build.c6
-rw-r--r--src/conntrack/parse.c16
-rw-r--r--src/conntrack/setter.c24
7 files changed, 79 insertions, 5 deletions
diff --git a/configure.in b/configure.in
index 37533c3..8bf6951 100644
--- a/configure.in
+++ b/configure.in
@@ -4,7 +4,7 @@ AC_INIT
AC_CANONICAL_SYSTEM
-AM_INIT_AUTOMAKE(libnetfilter_conntrack, 0.0.81)
+AM_INIT_AUTOMAKE(libnetfilter_conntrack, 0.0.82)
AC_PROG_CC
AM_PROG_LIBTOOL
diff --git a/include/internal.h b/include/internal.h
index 5a13c11..cf2d7a1 100644
--- a/include/internal.h
+++ b/include/internal.h
@@ -88,9 +88,17 @@ struct __nfct_tuple {
union __nfct_l4 l4dst;
};
+#define __DIR_ORIG 0
+#define __DIR_REPL 1
+#define __DIR_MAX __DIR_REPL+1
+
union __nfct_protoinfo {
struct {
u_int8_t state;
+ struct {
+ u_int8_t value;
+ u_int8_t mask;
+ } flags[__DIR_MAX];
} tcp;
};
@@ -104,10 +112,6 @@ struct __nfct_nat {
union __nfct_l4 l4min, l4max;
};
-#define __DIR_ORIG 0
-#define __DIR_REPL 1
-#define __DIR_MAX __DIR_REPL+1
-
struct nf_conntrack {
struct __nfct_tuple tuple[__DIR_MAX];
diff --git a/include/libnetfilter_conntrack/libnetfilter_conntrack.h b/include/libnetfilter_conntrack/libnetfilter_conntrack.h
index 3975dfc..7125414 100644
--- a/include/libnetfilter_conntrack/libnetfilter_conntrack.h
+++ b/include/libnetfilter_conntrack/libnetfilter_conntrack.h
@@ -98,6 +98,10 @@ enum nf_conntrack_attr {
ATTR_USE, /* u32 bits */
ATTR_ID, /* u32 bits */
ATTR_STATUS = 32, /* u32 bits */
+ ATTR_TCP_FLAGS_ORIG, /* u8 bits */
+ ATTR_TCP_FLAGS_REPL, /* u8 bits */
+ ATTR_TCP_MASK_ORIG, /* u8 bits */
+ ATTR_TCP_MASK_REPL, /* u8 bits */
ATTR_MAX
};
@@ -427,6 +431,22 @@ enum ip_conntrack_status {
IPS_FIXED_TIMEOUT = (1 << IPS_FIXED_TIMEOUT_BIT),
};
+/*
+ * TCP flags
+ */
+
+/* Window scaling is advertised by the sender */
+#define IP_CT_TCP_FLAG_WINDOW_SCALE 0x01
+
+/* SACK is permitted by the sender */
+#define IP_CT_TCP_FLAG_SACK_PERM 0x02
+
+/* This sender sent FIN first */
+#define IP_CT_TCP_FLAG_CLOSE_INIT 0x04
+
+/* Be liberal in window checking */
+#define IP_CT_TCP_FLAG_BE_LIBERAL 0x08
+
/*
* Old deprecated API, its use for new applications is *strongly discouraged*
*/
diff --git a/include/libnetfilter_conntrack/linux_nfnetlink_conntrack.h b/include/libnetfilter_conntrack/linux_nfnetlink_conntrack.h
index b268cc8..71baee1 100644
--- a/include/libnetfilter_conntrack/linux_nfnetlink_conntrack.h
+++ b/include/libnetfilter_conntrack/linux_nfnetlink_conntrack.h
@@ -87,6 +87,10 @@ enum ctattr_protoinfo {
enum ctattr_protoinfo_tcp {
CTA_PROTOINFO_TCP_UNSPEC,
CTA_PROTOINFO_TCP_STATE,
+ CTA_PROTOINFO_TCP_WSCALE_ORIGINAL,
+ CTA_PROTOINFO_TCP_WSCALE_REPLY,
+ CTA_PROTOINFO_TCP_FLAGS_ORIGINAL,
+ CTA_PROTOINFO_TCP_FLAGS_REPLY,
__CTA_PROTOINFO_TCP_MAX
};
#define CTA_PROTOINFO_TCP_MAX (__CTA_PROTOINFO_TCP_MAX - 1)
diff --git a/src/conntrack/build.c b/src/conntrack/build.c
index d04ad86..d66d038 100644
--- a/src/conntrack/build.c
+++ b/src/conntrack/build.c
@@ -97,6 +97,12 @@ void __build_protoinfo(struct nfnlhdr *req,
nest_proto = nfnl_nest(&req->nlh, size, CTA_PROTOINFO_TCP);
nfnl_addattr_l(&req->nlh, size, CTA_PROTOINFO_TCP_STATE,
&ct->protoinfo.tcp.state, sizeof(u_int8_t));
+ nfnl_addattr_l(&req->nlh, size,
+ CTA_PROTOINFO_TCP_FLAGS_ORIGINAL,
+ &ct->protoinfo.tcp.flags[0], sizeof(u_int16_t));
+ nfnl_addattr_l(&req->nlh, size,
+ CTA_PROTOINFO_TCP_FLAGS_REPLY,
+ &ct->protoinfo.tcp.flags[1], sizeof(u_int16_t));
nfnl_nest_end(&req->nlh, nest_proto);
nfnl_nest_end(&req->nlh, nest);
break;
diff --git a/src/conntrack/parse.c b/src/conntrack/parse.c
index db04789..9fbada4 100644
--- a/src/conntrack/parse.c
+++ b/src/conntrack/parse.c
@@ -160,6 +160,22 @@ static void __parse_protoinfo_tcp(const struct nfattr *attr,
*(u_int8_t *)NFA_DATA(tb[CTA_PROTOINFO_TCP_STATE-1]);
set_bit(ATTR_TCP_STATE, ct->set);
}
+
+ if (tb[CTA_PROTOINFO_TCP_FLAGS_ORIGINAL-1]) {
+ memcpy(&ct->protoinfo.tcp.flags[0],
+ NFA_DATA(tb[CTA_PROTOINFO_TCP_FLAGS_ORIGINAL-1]),
+ sizeof(u_int16_t));
+ set_bit(ATTR_TCP_FLAGS_ORIG, ct->set);
+ set_bit(ATTR_TCP_MASK_ORIG, ct->set);
+ }
+
+ if (tb[CTA_PROTOINFO_TCP_FLAGS_REPLY-1]) {
+ memcpy(&ct->protoinfo.tcp.flags[1],
+ NFA_DATA(tb[CTA_PROTOINFO_TCP_FLAGS_REPLY-1]),
+ sizeof(u_int16_t));
+ set_bit(ATTR_TCP_FLAGS_REPL, ct->set);
+ set_bit(ATTR_TCP_MASK_REPL, ct->set);
+ }
}
static void __parse_protoinfo(const struct nfattr *attr,
diff --git a/src/conntrack/setter.c b/src/conntrack/setter.c
index 255ab4d..afbf9be 100644
--- a/src/conntrack/setter.c
+++ b/src/conntrack/setter.c
@@ -107,6 +107,26 @@ static void set_attr_tcp_state(struct nf_conntrack *ct, const void *value)
ct->protoinfo.tcp.state = *((u_int8_t *) value);
}
+static void set_attr_tcp_flags_orig(struct nf_conntrack *ct, const void *value)
+{
+ ct->protoinfo.tcp.flags[__DIR_ORIG].value = *((u_int8_t *) value);
+}
+
+static void set_attr_tcp_mask_orig(struct nf_conntrack *ct, const void *value)
+{
+ ct->protoinfo.tcp.flags[__DIR_ORIG].mask = *((u_int8_t *) value);
+}
+
+static void set_attr_tcp_flags_repl(struct nf_conntrack *ct, const void *value)
+{
+ ct->protoinfo.tcp.flags[__DIR_REPL].value = *((u_int8_t *) value);
+}
+
+static void set_attr_tcp_mask_repl(struct nf_conntrack *ct, const void *value)
+{
+ ct->protoinfo.tcp.flags[__DIR_REPL].mask = *((u_int8_t *) value);
+}
+
static void set_attr_snat_ipv4(struct nf_conntrack *ct, const void *value)
{
ct->snat.min_ip = ct->snat.max_ip = *((u_int32_t *) value);
@@ -170,4 +190,8 @@ set_attr set_attr_array[] = {
[ATTR_TIMEOUT] = set_attr_timeout,
[ATTR_MARK] = set_attr_mark,
[ATTR_STATUS] = set_attr_status,
+ [ATTR_TCP_FLAGS_ORIG] = set_attr_tcp_flags_orig,
+ [ATTR_TCP_FLAGS_REPL] = set_attr_tcp_flags_repl,
+ [ATTR_TCP_MASK_ORIG] = set_attr_tcp_mask_orig,
+ [ATTR_TCP_MASK_REPL] = set_attr_tcp_mask_repl,
};