summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--include/internal/object.h10
-rw-r--r--include/libnetfilter_conntrack/Makefile.am2
-rw-r--r--include/libnetfilter_conntrack/libnetfilter_conntrack.h1
-rw-r--r--include/libnetfilter_conntrack/libnetfilter_conntrack_dccp.h33
-rw-r--r--src/conntrack/build.c38
-rw-r--r--src/conntrack/compare.c10
-rw-r--r--src/conntrack/getter.c6
-rw-r--r--src/conntrack/parse.c17
-rw-r--r--src/conntrack/setter.c6
-rw-r--r--src/conntrack/snprintf_default.c25
-rw-r--r--src/conntrack/snprintf_xml.c1
11 files changed, 138 insertions, 11 deletions
diff --git a/include/internal/object.h b/include/internal/object.h
index f76bf98..1db6b36 100644
--- a/include/internal/object.h
+++ b/include/internal/object.h
@@ -53,6 +53,9 @@ union __nfct_l4_src {
struct {
u_int16_t port;
} sctp;
+ struct {
+ u_int16_t port;
+ } dccp;
};
union __nfct_l4_dst {
@@ -70,6 +73,9 @@ union __nfct_l4_dst {
struct {
u_int16_t port;
} sctp;
+ struct {
+ u_int16_t port;
+ } dccp;
};
union __nfct_address {
@@ -110,7 +116,9 @@ union __nfct_protoinfo {
u_int8_t state;
u_int32_t vtag[__DIR_MAX];
} sctp;
-
+ struct {
+ u_int8_t state;
+ } dccp;
};
struct __nfct_counters {
diff --git a/include/libnetfilter_conntrack/Makefile.am b/include/libnetfilter_conntrack/Makefile.am
index c5f762f..fd36bfb 100644
--- a/include/libnetfilter_conntrack/Makefile.am
+++ b/include/libnetfilter_conntrack/Makefile.am
@@ -1,2 +1,2 @@
-pkginclude_HEADERS = libnetfilter_conntrack.h linux_nfnetlink_conntrack.h libnetfilter_conntrack_tcp.h libnetfilter_conntrack_udp.h libnetfilter_conntrack_icmp.h libnetfilter_conntrack_sctp.h libnetfilter_conntrack_ipv4.h libnetfilter_conntrack_ipv6.h
+pkginclude_HEADERS = libnetfilter_conntrack.h linux_nfnetlink_conntrack.h libnetfilter_conntrack_tcp.h libnetfilter_conntrack_udp.h libnetfilter_conntrack_icmp.h libnetfilter_conntrack_sctp.h libnetfilter_conntrack_dccp.h libnetfilter_conntrack_ipv4.h libnetfilter_conntrack_ipv6.h
diff --git a/include/libnetfilter_conntrack/libnetfilter_conntrack.h b/include/libnetfilter_conntrack/libnetfilter_conntrack.h
index f2b6dbb..3d25c6b 100644
--- a/include/libnetfilter_conntrack/libnetfilter_conntrack.h
+++ b/include/libnetfilter_conntrack/libnetfilter_conntrack.h
@@ -121,6 +121,7 @@ enum nf_conntrack_attr {
ATTR_SCTP_VTAG_ORIG, /* u32 bits */
ATTR_SCTP_VTAG_REPL, /* u32 bits */
ATTR_HELPER_NAME, /* string (30 bytes max) */
+ ATTR_DCCP_STATE = 56, /* u8 bits */
ATTR_MAX
};
diff --git a/include/libnetfilter_conntrack/libnetfilter_conntrack_dccp.h b/include/libnetfilter_conntrack/libnetfilter_conntrack_dccp.h
new file mode 100644
index 0000000..46138de
--- /dev/null
+++ b/include/libnetfilter_conntrack/libnetfilter_conntrack_dccp.h
@@ -0,0 +1,33 @@
+/*
+ * (C) 2009 by Pablo Neira Ayuso <pablo@netfilter.org>
+ *
+ * This software may be used and distributed according to the terms
+ * of the GNU General Public License, incorporated herein by reference.
+ */
+
+#ifndef _LIBNETFILTER_CONNTRACK_DCCP_H_
+#define _LIBNETFILTER_CONNTRACK_DCCP_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+enum dccp_state {
+ DCCP_CONNTRACK_NONE,
+ DCCP_CONNTRACK_REQUEST,
+ DCCP_CONNTRACK_RESPOND,
+ DCCP_CONNTRACK_PARTOPEN,
+ DCCP_CONNTRACK_OPEN,
+ DCCP_CONNTRACK_CLOSEREQ,
+ DCCP_CONNTRACK_CLOSING,
+ DCCP_CONNTRACK_TIMEWAIT,
+ DCCP_CONNTRACK_IGNORE,
+ DCCP_CONNTRACK_INVALID,
+ DCCP_CONNTRACK_MAX
+};
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
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",