From 7533cca286edee99db29eb1238653a2040738d3e Mon Sep 17 00:00:00 2001 From: Pablo Neira Ayuso Date: Tue, 14 Apr 2009 10:35:27 +0200 Subject: src: add initial DCCP support This patch adds initial DCCP support for libnetfilter_conntrack. Signed-off-by: Pablo Neira Ayuso --- src/conntrack/build.c | 38 +++++++++++++++++++++++++++++--------- src/conntrack/compare.c | 10 ++++++++++ src/conntrack/getter.c | 6 ++++++ src/conntrack/parse.c | 17 +++++++++++++++++ src/conntrack/setter.c | 6 ++++++ src/conntrack/snprintf_default.c | 25 +++++++++++++++++++++++++ src/conntrack/snprintf_xml.c | 1 + 7 files changed, 94 insertions(+), 9 deletions(-) (limited to 'src/conntrack') diff --git a/src/conntrack/build.c b/src/conntrack/build.c index 4b2e292..1738402 100644 --- a/src/conntrack/build.c +++ b/src/conntrack/build.c @@ -50,6 +50,7 @@ void __build_tuple_proto(struct nfnlhdr *req, case IPPROTO_UDP: case IPPROTO_TCP: case IPPROTO_SCTP: + case IPPROTO_DCCP: case IPPROTO_GRE: case IPPROTO_UDPLITE: nfnl_addattr_l(&req->nlh, size, CTA_PROTO_SRC_PORT, @@ -98,14 +99,20 @@ void __build_tuple(struct nfnlhdr *req, nfnl_nest_end(&req->nlh, nest); } -void __build_protoinfo(struct nfnlhdr *req, - size_t size, - const struct nf_conntrack *ct) +static void __build_protoinfo(struct nfnlhdr *req, size_t size, + const struct nf_conntrack *ct) { struct nfattr *nest, *nest_proto; switch(ct->tuple[__DIR_ORIG].protonum) { case IPPROTO_TCP: + if (!(test_bit(ATTR_TCP_STATE, ct->set) || + (test_bit(ATTR_TCP_FLAGS_ORIG, ct->set) && + test_bit(ATTR_TCP_MASK_ORIG, ct->set)) || + (test_bit(ATTR_TCP_FLAGS_REPL, ct->set) && + test_bit(ATTR_TCP_MASK_REPL, ct->set)))) { + break; + } nest = nfnl_nest(&req->nlh, size, CTA_PROTOINFO); nest_proto = nfnl_nest(&req->nlh, size, CTA_PROTOINFO_TCP); if (test_bit(ATTR_TCP_STATE, ct->set)) @@ -129,6 +136,11 @@ void __build_protoinfo(struct nfnlhdr *req, nfnl_nest_end(&req->nlh, nest); break; case IPPROTO_SCTP: + if (!(test_bit(ATTR_SCTP_STATE, ct->set) && + (test_bit(ATTR_SCTP_VTAG_ORIG, ct->set) && + test_bit(ATTR_SCTP_VTAG_REPL, ct->set)))) { + break; + } nest = nfnl_nest(&req->nlh, size, CTA_PROTOINFO); nest_proto = nfnl_nest(&req->nlh, size, CTA_PROTOINFO_SCTP); if (test_bit(ATTR_SCTP_STATE, ct->set)) @@ -147,6 +159,19 @@ void __build_protoinfo(struct nfnlhdr *req, nfnl_nest_end(&req->nlh, nest_proto); nfnl_nest_end(&req->nlh, nest); break; + case IPPROTO_DCCP: + if (!(test_bit(ATTR_DCCP_STATE, ct->set))) + break; + + nest = nfnl_nest(&req->nlh, size, CTA_PROTOINFO); + nest_proto = nfnl_nest(&req->nlh, size, CTA_PROTOINFO_DCCP); + if (test_bit(ATTR_DCCP_STATE, ct->set)) + nfnl_addattr_l(&req->nlh, size, + CTA_PROTOINFO_DCCP_STATE, + &ct->protoinfo.dccp.state, + sizeof(u_int8_t)); + nfnl_nest_end(&req->nlh, nest_proto); + nfnl_nest_end(&req->nlh, nest); default: break; } @@ -404,12 +429,7 @@ int __build_conntrack(struct nfnl_subsys_handle *ssh, if (test_bit(ATTR_SECMARK, ct->set)) __build_secmark(req, size, ct); - if (test_bit(ATTR_TCP_STATE, ct->set) || - (test_bit(ATTR_TCP_FLAGS_ORIG, ct->set) && - test_bit(ATTR_TCP_MASK_ORIG, ct->set)) || - (test_bit(ATTR_TCP_FLAGS_REPL, ct->set) && - test_bit(ATTR_TCP_MASK_REPL, ct->set))) - __build_protoinfo(req, size, ct); + __build_protoinfo(req, size, ct); if (test_bit(ATTR_SNAT_IPV4, ct->set) && test_bit(ATTR_SNAT_PORT, ct->set)) diff --git a/src/conntrack/compare.c b/src/conntrack/compare.c index 1be1c71..ba3fdf8 100644 --- a/src/conntrack/compare.c +++ b/src/conntrack/compare.c @@ -352,6 +352,14 @@ cmp_sctp_state(const struct nf_conntrack *ct1, return (ct1->protoinfo.sctp.state == ct2->protoinfo.sctp.state); } +static int +cmp_dccp_state(const struct nf_conntrack *ct1, + const struct nf_conntrack *ct2, + unsigned int flags) +{ + return (ct1->protoinfo.dccp.state == ct2->protoinfo.dccp.state); +} + static int cmp_meta(const struct nf_conntrack *ct1, const struct nf_conntrack *ct2, unsigned int flags) @@ -368,6 +376,8 @@ static int cmp_meta(const struct nf_conntrack *ct1, return 0; if (!__cmp(ATTR_SCTP_STATE, ct1, ct2, flags, cmp_sctp_state)) return 0; + if (!__cmp(ATTR_DCCP_STATE, ct1, ct2, flags, cmp_dccp_state)) + return 0; return 1; } diff --git a/src/conntrack/getter.c b/src/conntrack/getter.c index 65661d4..2338db2 100644 --- a/src/conntrack/getter.c +++ b/src/conntrack/getter.c @@ -287,6 +287,11 @@ static const void *get_attr_helper_name(const struct nf_conntrack *ct) return ct->helper_name; } +static const void *get_attr_dccp_state(const struct nf_conntrack *ct) +{ + return &ct->protoinfo.dccp.state; +} + 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, @@ -344,4 +349,5 @@ get_attr get_attr_array[ATTR_MAX] = { [ATTR_SCTP_VTAG_ORIG] = get_attr_sctp_vtag_orig, [ATTR_SCTP_VTAG_REPL] = get_attr_sctp_vtag_repl, [ATTR_HELPER_NAME] = get_attr_helper_name, + [ATTR_DCCP_STATE] = get_attr_dccp_state, }; diff --git a/src/conntrack/parse.c b/src/conntrack/parse.c index d453bc6..9a42ed7 100644 --- a/src/conntrack/parse.c +++ b/src/conntrack/parse.c @@ -244,6 +244,20 @@ static void __parse_protoinfo_sctp(const struct nfattr *attr, } +static void __parse_protoinfo_dccp(const struct nfattr *attr, + struct nf_conntrack *ct) +{ + struct nfattr *tb[CTA_PROTOINFO_DCCP_MAX]; + + nfnl_parse_nested(tb, CTA_PROTOINFO_DCCP_MAX, attr); + + if (tb[CTA_PROTOINFO_DCCP_STATE-1]) { + ct->protoinfo.dccp.state = + *(u_int8_t *)NFA_DATA(tb[CTA_PROTOINFO_DCCP_STATE-1]); + set_bit(ATTR_DCCP_STATE, ct->set); + } +} + static void __parse_protoinfo(const struct nfattr *attr, struct nf_conntrack *ct) { @@ -256,6 +270,9 @@ static void __parse_protoinfo(const struct nfattr *attr, if (tb[CTA_PROTOINFO_SCTP-1]) __parse_protoinfo_sctp(tb[CTA_PROTOINFO_SCTP-1], ct); + + if (tb[CTA_PROTOINFO_DCCP-1]) + __parse_protoinfo_dccp(tb[CTA_PROTOINFO_DCCP-1], ct); } static void __parse_counters(const struct nfattr *attr, diff --git a/src/conntrack/setter.c b/src/conntrack/setter.c index 6e275ab..481fad1 100644 --- a/src/conntrack/setter.c +++ b/src/conntrack/setter.c @@ -314,6 +314,11 @@ static void set_attr_helper_name(struct nf_conntrack *ct, const void *value) ct->helper_name[__NFCT_HELPER_NAMELEN-1] = '\0'; } +static void set_attr_dccp_state(struct nf_conntrack *ct, const void *value) +{ + ct->protoinfo.dccp.state = *((u_int8_t *) value); +} + static void set_attr_do_nothing(struct nf_conntrack *ct, const void *value) {} set_attr set_attr_array[ATTR_MAX] = { @@ -373,4 +378,5 @@ set_attr set_attr_array[ATTR_MAX] = { [ATTR_SCTP_VTAG_ORIG] = set_attr_sctp_vtag_orig, [ATTR_SCTP_VTAG_REPL] = set_attr_sctp_vtag_repl, [ATTR_HELPER_NAME] = set_attr_helper_name, + [ATTR_DCCP_STATE] = set_attr_dccp_state, }; diff --git a/src/conntrack/snprintf_default.c b/src/conntrack/snprintf_default.c index dbc5fb1..4802c47 100644 --- a/src/conntrack/snprintf_default.c +++ b/src/conntrack/snprintf_default.c @@ -16,6 +16,7 @@ static char *proto2str[IPPROTO_MAX] = { [IPPROTO_SCTP] = "sctp", [IPPROTO_GRE] = "gre", [IPPROTO_UDPLITE] = "udplite", + [IPPROTO_DCCP] = "dccp", }; static char *l3proto2str[AF_MAX] = { @@ -47,6 +48,19 @@ static const char *sctp_states[] = { "SHUTDOWN_ACK_SENT", }; +static const char *dccp_states[] = { + "NONE", + "REQUEST", + "RESPOND", + "PARTOPEN", + "OPEN", + "CLOSEREQ", + "CLOSING", + "TIMEWAIT", + "IGNORE", + "INVALID", +}; + static int __snprintf_l3protocol(char *buf, unsigned int len, const struct nf_conntrack *ct) @@ -86,6 +100,12 @@ int __snprintf_protoinfo_sctp(char *buf, { return snprintf(buf, len, "%s ", sctp_states[ct->protoinfo.sctp.state]); } +int __snprintf_protoinfo_dccp(char *buf, + unsigned int len, + const struct nf_conntrack *ct) +{ + return snprintf(buf, len, "%s ", dccp_states[ct->protoinfo.dccp.state]); +} int __snprintf_address_ipv4(char *buf, unsigned int len, @@ -288,6 +308,11 @@ int __snprintf_conntrack_default(char *buf, BUFFER_SIZE(ret, size, len, offset); } + if (test_bit(ATTR_DCCP_STATE, ct->set)) { + ret = __snprintf_protoinfo_dccp(buf+offset, len, ct); + BUFFER_SIZE(ret, size, len, offset); + } + ret = __snprintf_address(buf+offset, len, &ct->tuple[__DIR_ORIG]); BUFFER_SIZE(ret, size, len, offset); diff --git a/src/conntrack/snprintf_xml.c b/src/conntrack/snprintf_xml.c index 5dbba9f..ff34e86 100644 --- a/src/conntrack/snprintf_xml.c +++ b/src/conntrack/snprintf_xml.c @@ -62,6 +62,7 @@ static char *proto2str[IPPROTO_MAX] = { [IPPROTO_SCTP] = "sctp", [IPPROTO_GRE] = "gre", [IPPROTO_UDPLITE] = "udplite", + [IPPROTO_DCCP] = "dccp", }; static char *l3proto2str[AF_MAX] = { [AF_INET] = "ipv4", -- cgit v1.2.3