All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH] [LIBNETFILTER_CONNTRACK] SCTP support
@ 2008-05-20 22:56 Pablo Neira Ayuso
  0 siblings, 0 replies; only message in thread
From: Pablo Neira Ayuso @ 2008-05-20 22:56 UTC (permalink / raw)
  To: Netfilter Development Mailinglist

[-- Attachment #1: Type: text/plain, Size: 164 bytes --]

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

[-- Attachment #2: x --]
[-- Type: text/plain, Size: 10493 bytes --]

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);
 

^ permalink raw reply related	[flat|nested] only message in thread

only message in thread, other threads:[~2008-05-20 22:56 UTC | newest]

Thread overview: (only message) (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2008-05-20 22:56 [PATCH] [LIBNETFILTER_CONNTRACK] SCTP support Pablo Neira Ayuso

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.