From fb61c68dd0ba2e6ce98516ddbbd3b10638f4bcea Mon Sep 17 00:00:00 2001 From: Pablo Neira Ayuso Date: Tue, 29 Dec 2009 18:47:10 +0100 Subject: src: add support for TCP window scale factor This patch adds the missing bits to support the modification of the TCP window scale factor in a conntrack entry. The kernel support has been already there since 2.6.23. Signed-off-by: Pablo Neira Ayuso --- include/internal/object.h | 1 + include/libnetfilter_conntrack/libnetfilter_conntrack.h | 2 ++ src/conntrack/build.c | 10 ++++++++++ src/conntrack/copy.c | 16 ++++++++++++++++ src/conntrack/getter.c | 12 ++++++++++++ src/conntrack/parse.c | 14 ++++++++++++++ 6 files changed, 55 insertions(+) diff --git a/include/internal/object.h b/include/internal/object.h index 04d64b6..514ddee 100644 --- a/include/internal/object.h +++ b/include/internal/object.h @@ -126,6 +126,7 @@ union __nfct_protoinfo { u_int8_t value; u_int8_t mask; } flags[__DIR_MAX]; + u_int8_t wscale[__DIR_MAX]; } tcp; struct { u_int8_t state; diff --git a/include/libnetfilter_conntrack/libnetfilter_conntrack.h b/include/libnetfilter_conntrack/libnetfilter_conntrack.h index 93645a3..48b3621 100644 --- a/include/libnetfilter_conntrack/libnetfilter_conntrack.h +++ b/include/libnetfilter_conntrack/libnetfilter_conntrack.h @@ -124,6 +124,8 @@ enum nf_conntrack_attr { ATTR_DCCP_STATE = 56, /* u8 bits */ ATTR_DCCP_ROLE, /* u8 bits */ ATTR_DCCP_HANDSHAKE_SEQ, /* u64 bits */ + ATTR_TCP_WSCALE_ORIG, /* u8 bits */ + ATTR_TCP_WSCALE_REPL = 60, /* u8 bits */ ATTR_MAX }; diff --git a/src/conntrack/build.c b/src/conntrack/build.c index 91eca7d..e8bb9ac 100644 --- a/src/conntrack/build.c +++ b/src/conntrack/build.c @@ -125,6 +125,16 @@ static void __build_protoinfo(struct nfnlhdr *req, size_t size, CTA_PROTOINFO_TCP_FLAGS_REPLY, &ct->protoinfo.tcp.flags[1], sizeof(u_int16_t)); + if (test_bit(ATTR_TCP_WSCALE_ORIG, ct->set)) + nfnl_addattr_l(&req->nlh, size, + CTA_PROTOINFO_TCP_WSCALE_ORIGINAL, + &ct->protoinfo.tcp.wscale[__DIR_ORIG], + sizeof(u_int8_t)); + if (test_bit(ATTR_TCP_WSCALE_REPL, ct->set)) + nfnl_addattr_l(&req->nlh, size, + CTA_PROTOINFO_TCP_WSCALE_REPLY, + &ct->protoinfo.tcp.wscale[__DIR_REPL], + sizeof(u_int8_t)); nfnl_nest_end(&req->nlh, nest_proto); nfnl_nest_end(&req->nlh, nest); break; diff --git a/src/conntrack/copy.c b/src/conntrack/copy.c index 63bdf0b..7f7514d 100644 --- a/src/conntrack/copy.c +++ b/src/conntrack/copy.c @@ -224,6 +224,20 @@ static void copy_attr_tcp_mask_repl(struct nf_conntrack *dest, orig->protoinfo.tcp.flags[__DIR_REPL].mask; } +static void copy_attr_tcp_wscale_orig(struct nf_conntrack *dest, + const struct nf_conntrack *orig) +{ + dest->protoinfo.tcp.wscale[__DIR_ORIG] = + orig->protoinfo.tcp.wscale[__DIR_ORIG]; +} + +static void copy_attr_tcp_wscale_repl(struct nf_conntrack *dest, + const struct nf_conntrack *orig) +{ + dest->protoinfo.tcp.wscale[__DIR_REPL] = + orig->protoinfo.tcp.wscale[__DIR_REPL]; +} + static void copy_attr_sctp_state(struct nf_conntrack *dest, const struct nf_conntrack *orig) { @@ -455,4 +469,6 @@ copy_attr copy_attr_array[ATTR_MAX] = { [ATTR_DCCP_STATE] = copy_attr_dccp_state, [ATTR_DCCP_ROLE] = copy_attr_dccp_role, [ATTR_DCCP_HANDSHAKE_SEQ] = copy_attr_dccp_handshake_seq, + [ATTR_TCP_WSCALE_ORIG] = copy_attr_tcp_wscale_orig, + [ATTR_TCP_WSCALE_REPL] = copy_attr_tcp_wscale_repl, }; diff --git a/src/conntrack/getter.c b/src/conntrack/getter.c index 96273a0..507a3a2 100644 --- a/src/conntrack/getter.c +++ b/src/conntrack/getter.c @@ -167,6 +167,16 @@ static const void *get_attr_tcp_mask_repl(const struct nf_conntrack *ct) return &ct->protoinfo.tcp.flags[__DIR_REPL].mask; } +static const void *get_attr_tcp_wscale_orig(const struct nf_conntrack *ct) +{ + return &ct->protoinfo.tcp.wscale[__DIR_ORIG]; +} + +static const void *get_attr_tcp_wscale_repl(const struct nf_conntrack *ct) +{ + return &ct->protoinfo.tcp.wscale[__DIR_REPL]; +} + static const void *get_attr_sctp_state(const struct nf_conntrack *ct) { return &ct->protoinfo.sctp.state; @@ -362,4 +372,6 @@ get_attr get_attr_array[ATTR_MAX] = { [ATTR_DCCP_STATE] = get_attr_dccp_state, [ATTR_DCCP_ROLE] = get_attr_dccp_role, [ATTR_DCCP_HANDSHAKE_SEQ] = get_attr_dccp_handshake_seq, + [ATTR_TCP_WSCALE_ORIG] = get_attr_tcp_wscale_orig, + [ATTR_TCP_WSCALE_REPL] = get_attr_tcp_wscale_repl, }; diff --git a/src/conntrack/parse.c b/src/conntrack/parse.c index bf72545..0e0cd58 100644 --- a/src/conntrack/parse.c +++ b/src/conntrack/parse.c @@ -200,6 +200,20 @@ static void __parse_protoinfo_tcp(const struct nfattr *attr, set_bit(ATTR_TCP_STATE, ct->set); } + if (tb[CTA_PROTOINFO_TCP_WSCALE_ORIGINAL-1]) { + memcpy(&ct->protoinfo.tcp.wscale[__DIR_ORIG], + NFA_DATA(tb[CTA_PROTOINFO_TCP_WSCALE_ORIGINAL-1]), + sizeof(u_int8_t)); + set_bit(ATTR_TCP_WSCALE_ORIG, ct->set); + } + + if (tb[CTA_PROTOINFO_TCP_WSCALE_REPLY-1]) { + memcpy(&ct->protoinfo.tcp.wscale[__DIR_REPL], + NFA_DATA(tb[CTA_PROTOINFO_TCP_WSCALE_REPLY-1]), + sizeof(u_int8_t)); + set_bit(ATTR_TCP_WSCALE_REPL, 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]), -- cgit v1.2.3