[PATCH] [LIBNETFILTER_CONNTRACK] SCTP support

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Attached SCTP support for libnetfilter_conntrack in case that you want
to test the kernel [PATCH 2/4].

-- 
"Los honestos son inadaptados sociales" -- Les Luthiers
diff --git a/include/internal.h b/include/internal.h
index 039c64c..6661dbe 100644
--- a/include/internal.h
+++ b/include/internal.h
@@ -130,6 +130,11 @@ union __nfct_protoinfo {
 			u_int8_t mask;
 		} flags[__DIR_MAX];
 	} tcp;
+	struct {
+		u_int8_t state;
+		u_int32_t vtag[__DIR_MAX];
+	} sctp;
+
 };
 
 struct __nfct_counters {
diff --git a/include/libnetfilter_conntrack/libnetfilter_conntrack.h b/include/libnetfilter_conntrack/libnetfilter_conntrack.h
index 075ac3a..a043f91 100644
--- a/include/libnetfilter_conntrack/libnetfilter_conntrack.h
+++ b/include/libnetfilter_conntrack/libnetfilter_conntrack.h
@@ -117,6 +117,9 @@ enum nf_conntrack_attr {
 	ATTR_REPL_NAT_SEQ_CORRECTION_POS,	/* u32 bits */
 	ATTR_REPL_NAT_SEQ_OFFSET_BEFORE,	/* u32 bits */
 	ATTR_REPL_NAT_SEQ_OFFSET_AFTER,		/* u32 bits */
+	ATTR_SCTP_STATE = 52,			/* u8 bits */
+	ATTR_SCTP_VTAG_ORIG,			/* u32 bits */
+	ATTR_SCTP_VTAG_REPL,			/* u32 bits */
 	ATTR_MAX
 };
 
diff --git a/include/libnetfilter_conntrack/linux_nfnetlink_conntrack.h b/include/libnetfilter_conntrack/linux_nfnetlink_conntrack.h
index 7f0fe96..3b2d869 100644
--- a/include/libnetfilter_conntrack/linux_nfnetlink_conntrack.h
+++ b/include/libnetfilter_conntrack/linux_nfnetlink_conntrack.h
@@ -84,6 +84,8 @@ enum ctattr_l4proto {
 enum ctattr_protoinfo {
 	CTA_PROTOINFO_UNSPEC,
 	CTA_PROTOINFO_TCP,
+	CTA_PROTOINFO_DCCP,
+	CTA_PROTOINFO_SCTP,
 	__CTA_PROTOINFO_MAX
 };
 #define CTA_PROTOINFO_MAX (__CTA_PROTOINFO_MAX - 1)
@@ -99,6 +101,22 @@ enum ctattr_protoinfo_tcp {
 };
 #define CTA_PROTOINFO_TCP_MAX (__CTA_PROTOINFO_TCP_MAX - 1)
 
+enum ctattr_protoinfo_dccp {
+	CTA_PROTOINFO_DCCP_UNSPEC,
+	CTA_PROTOINFO_DCCP_STATE,
+	__CTA_PROTOINFO_DCCP_MAX
+};
+#define CTA_PROTOINFO_DCCP_MAX (__CTA_PROTOINFO_DCCP_MAX - 1)
+
+enum ctattr_protoinfo_sctp {
+	CTA_PROTOINFO_SCTP_UNSPEC,
+	CTA_PROTOINFO_SCTP_STATE,
+	CTA_PROTOINFO_SCTP_VTAG_ORIGINAL,
+	CTA_PROTOINFO_SCTP_VTAG_REPLY,
+	__CTA_PROTOINFO_SCTP_MAX
+};
+#define CTA_PROTOINFO_SCTP_MAX (__CTA_PROTOINFO_SCTP_MAX - 1)
+
 enum ctattr_counters {
 	CTA_COUNTERS_UNSPEC,
 	CTA_COUNTERS_PACKETS,		/* old 64bit counters */
diff --git a/src/conntrack/build.c b/src/conntrack/build.c
index 638fbe2..f11af42 100644
--- a/src/conntrack/build.c
+++ b/src/conntrack/build.c
@@ -123,6 +123,25 @@ void __build_protoinfo(struct nfnlhdr *req,
 		nfnl_nest_end(&req->nlh, nest_proto);
 		nfnl_nest_end(&req->nlh, nest);
 		break;
+	case IPPROTO_SCTP:
+		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))
+			nfnl_addattr_l(&req->nlh, size,
+				       CTA_PROTOINFO_SCTP_STATE,
+				       &ct->protoinfo.sctp.state,
+				       sizeof(u_int8_t));
+		if (test_bit(ATTR_SCTP_VTAG_ORIG, ct->set))
+			nfnl_addattr32(&req->nlh, size,
+				    CTA_PROTOINFO_SCTP_VTAG_ORIGINAL,
+				    htonl(ct->protoinfo.sctp.vtag[__DIR_ORIG]));
+		if (test_bit(ATTR_SCTP_VTAG_REPL, ct->set))
+			nfnl_addattr32(&req->nlh, size,
+				    CTA_PROTOINFO_SCTP_VTAG_REPLY,
+				    htonl(ct->protoinfo.sctp.vtag[__DIR_REPL]));
+		nfnl_nest_end(&req->nlh, nest_proto);
+		nfnl_nest_end(&req->nlh, nest);
+		break;
 	default:
 		break;
 	}
diff --git a/src/conntrack/compare.c b/src/conntrack/compare.c
index cd51f9d..d30a902 100644
--- a/src/conntrack/compare.c
+++ b/src/conntrack/compare.c
@@ -222,6 +222,11 @@ static int cmp_meta(const struct nf_conntrack *ct1,
 	    ct1->protoinfo.tcp.state != ct2->protoinfo.tcp.state)
 	    	return 0;
 
+	if (test_bit(ATTR_SCTP_STATE, ct1->set) &&
+	    test_bit(ATTR_SCTP_STATE, ct2->set) &&
+	    ct1->protoinfo.sctp.state != ct2->protoinfo.sctp.state)
+	    	return 0;
+
 	return 1;
 }
 
diff --git a/src/conntrack/copy.c b/src/conntrack/copy.c
index 142f868..562f801 100644
--- a/src/conntrack/copy.c
+++ b/src/conntrack/copy.c
@@ -224,6 +224,26 @@ static void copy_attr_tcp_mask_repl(struct nf_conntrack *dest,
 		orig->protoinfo.tcp.flags[__DIR_REPL].mask;
 }
 
+static void copy_attr_sctp_state(struct nf_conntrack *dest,
+				 const struct nf_conntrack *orig)
+{
+	dest->protoinfo.sctp.state = orig->protoinfo.sctp.state;
+}
+
+static void copy_attr_sctp_vtag_orig(struct nf_conntrack *dest,
+				     const struct nf_conntrack *orig)
+{
+	dest->protoinfo.sctp.vtag[__DIR_ORIG] =
+		orig->protoinfo.sctp.vtag[__DIR_ORIG];
+}
+
+static void copy_attr_sctp_vtag_repl(struct nf_conntrack *dest,
+				     const struct nf_conntrack *orig)
+{
+	dest->protoinfo.sctp.vtag[__DIR_REPL] =
+		orig->protoinfo.sctp.vtag[__DIR_REPL];
+}
+
 static void copy_attr_snat_ipv4(struct nf_conntrack *dest,
 				const struct nf_conntrack *orig)
 {
@@ -403,4 +423,7 @@ copy_attr copy_attr_array[] = {
 	[ATTR_REPL_NAT_SEQ_CORRECTION_POS]	= copy_attr_repl_cor_pos,
 	[ATTR_REPL_NAT_SEQ_OFFSET_BEFORE]	= copy_attr_repl_off_bfr,
 	[ATTR_REPL_NAT_SEQ_OFFSET_AFTER]	= copy_attr_repl_off_aft,
+	[ATTR_SCTP_STATE]		= copy_attr_sctp_state,
+	[ATTR_SCTP_VTAG_ORIG]		= copy_attr_sctp_vtag_orig,
+	[ATTR_SCTP_VTAG_REPL]		= copy_attr_sctp_vtag_repl,
 };
diff --git a/src/conntrack/getter.c b/src/conntrack/getter.c
index 48ba386..8591f88 100644
--- a/src/conntrack/getter.c
+++ b/src/conntrack/getter.c
@@ -167,6 +167,21 @@ 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_sctp_state(const struct nf_conntrack *ct)
+{
+	return &ct->protoinfo.sctp.state;
+}
+
+static const void *get_attr_sctp_vtag_orig(const struct nf_conntrack *ct)
+{
+	return &ct->protoinfo.sctp.vtag[__DIR_ORIG];
+}
+
+static const void *get_attr_sctp_vtag_repl(const struct nf_conntrack *ct)
+{
+	return &ct->protoinfo.sctp.vtag[__DIR_REPL];
+}
+
 static const void *get_attr_snat_ipv4(const struct nf_conntrack *ct)
 {
 	return &ct->snat.min_ip;
@@ -320,4 +335,7 @@ get_attr get_attr_array[] = {
 	[ATTR_REPL_NAT_SEQ_CORRECTION_POS]	= get_attr_repl_cor_pos,
 	[ATTR_REPL_NAT_SEQ_OFFSET_BEFORE]	= get_attr_repl_off_bfr,
 	[ATTR_REPL_NAT_SEQ_OFFSET_AFTER]	= get_attr_repl_off_aft,
+	[ATTR_SCTP_STATE]		= get_attr_sctp_state,
+	[ATTR_SCTP_VTAG_ORIG]		= get_attr_sctp_vtag_orig,
+	[ATTR_SCTP_VTAG_REPL]		= get_attr_sctp_vtag_repl,
 };
diff --git a/src/conntrack/parse.c b/src/conntrack/parse.c
index c21f304..a18e3ad 100644
--- a/src/conntrack/parse.c
+++ b/src/conntrack/parse.c
@@ -217,6 +217,33 @@ static void __parse_protoinfo_tcp(const struct nfattr *attr,
 	}
 }
 
+static void __parse_protoinfo_sctp(const struct nfattr *attr, 
+				   struct nf_conntrack *ct)
+{
+	struct nfattr *tb[CTA_PROTOINFO_SCTP_MAX];
+
+	nfnl_parse_nested(tb, CTA_PROTOINFO_SCTP_MAX, attr);
+
+	if (tb[CTA_PROTOINFO_SCTP_STATE-1]) {
+                ct->protoinfo.sctp.state =
+                        *(u_int8_t *)NFA_DATA(tb[CTA_PROTOINFO_SCTP_STATE-1]);
+		set_bit(ATTR_SCTP_STATE, ct->set);
+	}
+
+	if (tb[CTA_PROTOINFO_SCTP_VTAG_ORIGINAL-1]) {
+		ct->protoinfo.sctp.vtag[__DIR_ORIG] = 
+			ntohl(*(u_int32_t *)NFA_DATA(tb[CTA_PROTOINFO_SCTP_VTAG_ORIGINAL-1]));
+		set_bit(ATTR_SCTP_VTAG_ORIG, ct->set);
+	}
+
+	if (tb[CTA_PROTOINFO_SCTP_VTAG_REPLY-1]) {
+		ct->protoinfo.sctp.vtag[__DIR_ORIG] = 
+			ntohl(*(u_int32_t *)NFA_DATA(tb[CTA_PROTOINFO_SCTP_VTAG_REPLY-1]));
+		set_bit(ATTR_SCTP_VTAG_ORIG, ct->set);
+	}
+
+}
+
 static void __parse_protoinfo(const struct nfattr *attr,
 			      struct nf_conntrack *ct)
 {
@@ -224,10 +251,11 @@ static void __parse_protoinfo(const struct nfattr *attr,
 
 	nfnl_parse_nested(tb, CTA_PROTOINFO_MAX, attr);
 
-	if (!tb[CTA_PROTOINFO_TCP-1])
-		return;
+	if (tb[CTA_PROTOINFO_TCP-1])
+		__parse_protoinfo_tcp(tb[CTA_PROTOINFO_TCP-1], ct);
 
-	__parse_protoinfo_tcp(tb[CTA_PROTOINFO_TCP-1], ct);
+	if (tb[CTA_PROTOINFO_SCTP-1])
+		__parse_protoinfo_sctp(tb[CTA_PROTOINFO_SCTP-1], ct);
 }
 
 static void __parse_counters(const struct nfattr *attr,
diff --git a/src/conntrack/setter.c b/src/conntrack/setter.c
index 52a2aab..53698bf 100644
--- a/src/conntrack/setter.c
+++ b/src/conntrack/setter.c
@@ -170,6 +170,21 @@ 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_sctp_state(struct nf_conntrack *ct, const void *value)
+{
+	ct->protoinfo.sctp.state = *((u_int8_t *) value);
+}
+
+static void set_attr_sctp_vtag_orig(struct nf_conntrack *ct, const void *value)
+{
+	ct->protoinfo.sctp.vtag[__DIR_ORIG] = *((u_int32_t *) value);
+}
+
+static void set_attr_sctp_vtag_repl(struct nf_conntrack *ct, const void *value)
+{
+	ct->protoinfo.sctp.vtag[__DIR_REPL] = *((u_int32_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);
@@ -340,4 +355,7 @@ set_attr set_attr_array[] = {
 	[ATTR_REPL_NAT_SEQ_CORRECTION_POS] 	= set_attr_repl_cor_pos,
 	[ATTR_REPL_NAT_SEQ_OFFSET_BEFORE] 	= set_attr_repl_off_aft,
 	[ATTR_REPL_NAT_SEQ_OFFSET_AFTER] 	= set_attr_repl_off_bfr,
+	[ATTR_SCTP_STATE]	= set_attr_sctp_state,
+	[ATTR_SCTP_VTAG_ORIG]	= set_attr_sctp_vtag_orig,
+	[ATTR_SCTP_VTAG_REPL]	= set_attr_sctp_vtag_repl,
 };
diff --git a/src/conntrack/snprintf_default.c b/src/conntrack/snprintf_default.c
index e2573df..a0e3a30 100644
--- a/src/conntrack/snprintf_default.c
+++ b/src/conntrack/snprintf_default.c
@@ -34,6 +34,17 @@ static const char *states[] = {
 	"LISTEN"
 };
 
+static const char *sctp_states[] = {
+	"NONE",
+	"CLOSED",
+	"COOKIE_WAIT",
+	"COOKIE_ECHOED",
+	"ESTABLISHED",
+	"SHUTDOWN_SENT",
+	"SHUTDOWN_RECD",
+	"SHUTDOWN_ACK_SENT",
+};
+
 static int __snprintf_l3protocol(char *buf,
 				 unsigned int len,
 				 const struct nf_conntrack *ct)
@@ -65,8 +76,15 @@ int __snprintf_protoinfo(char *buf,
 			 unsigned int len,
 			 const struct nf_conntrack *ct)
 {
+
 	return snprintf(buf, len, "%s ", states[ct->protoinfo.tcp.state]);
 }
+int __snprintf_protoinfo_sctp(char *buf, 
+			      unsigned int len,
+			      const struct nf_conntrack *ct)
+{
+	return snprintf(buf, len, "%s ", sctp_states[ct->protoinfo.sctp.state]);
+}
 
 int __snprintf_address_ipv4(char *buf,
 			    unsigned int len,
@@ -260,6 +278,11 @@ int __snprintf_conntrack_default(char *buf,
 		BUFFER_SIZE(ret, size, len, offset);
 	}
 
+	if (test_bit(ATTR_SCTP_STATE, ct->set)) {
+		ret = __snprintf_protoinfo_sctp(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);
 

[Index of Archives]     [Netfitler Users]     [LARTC]     [Bugtraq]     [Yosemite Forum]

  Powered by Linux