[PATCH][libnetfilter_conntrack] add support for explicit helper assignment

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

 



This patch adds support for the explicit helper assignment to
libnetfilter_conntrack. You can use it to test the load-on-demand helper
 modules via ctnetlink.

-- 
"Los honestos son inadaptados sociales" -- Les Luthiers
[PATCH][libnetfilter_conntrack] add support for explicit helper assignment

This patch adds support for explicit helper assignment.

Signed-off-by: Pablo Neira Ayuso <pablo@xxxxxxxxxxxxx>

diff --git a/include/internal/extern.h b/include/internal/extern.h
index a43cde7..0caa30c 100644
--- a/include/internal/extern.h
+++ b/include/internal/extern.h
@@ -9,4 +9,6 @@ extern filter_attr 	filter_attr_array[];
 extern set_exp_attr	set_exp_attr_array[];
 extern get_exp_attr	get_exp_attr_array[];
 
+extern const char 	*helper_id_to_name[];
+
 #endif
diff --git a/include/internal/object.h b/include/internal/object.h
index e39a576..509f54b 100644
--- a/include/internal/object.h
+++ b/include/internal/object.h
@@ -137,6 +137,7 @@ struct nf_conntrack {
 	u_int32_t 	status;
 	u_int32_t	use;
 	u_int32_t	id;
+	u_int32_t	helper_id;
 
 	union __nfct_protoinfo 	protoinfo;
 	struct __nfct_counters 	counters[__DIR_MAX];
diff --git a/include/libnetfilter_conntrack/libnetfilter_conntrack.h b/include/libnetfilter_conntrack/libnetfilter_conntrack.h
index 46eed0a..ee22fa9 100644
--- a/include/libnetfilter_conntrack/libnetfilter_conntrack.h
+++ b/include/libnetfilter_conntrack/libnetfilter_conntrack.h
@@ -120,9 +120,26 @@ enum nf_conntrack_attr {
 	ATTR_SCTP_STATE = 52,			/* u8 bits */
 	ATTR_SCTP_VTAG_ORIG,			/* u32 bits */
 	ATTR_SCTP_VTAG_REPL,			/* u32 bits */
+	ATTR_HELPER_ID,				/* u32 bits */
 	ATTR_MAX
 };
 
+/* helper id's */
+
+enum nf_conntrack_helper_id {
+	NFCT_HELPER_UNSPEC = 0,
+	NFCT_HELPER_AMANDA,
+	NFCT_HELPER_FTP,
+	NFCT_HELPER_H323,
+	NFCT_HELPER_IRC = 4,
+	NFCT_HELPER_NETBIOS_NS,
+	NFCT_HELPER_PPTP,
+	NFCT_HELPER_SANE,
+	NFCT_HELPER_SIP = 8,
+	NFCT_HELPER_TFTP,
+	NFCT_HELPER_MAX
+};
+
 /* message type */
 enum nf_conntrack_msg_type {
 	NFCT_T_UNKNOWN = 0,
diff --git a/src/conntrack/build.c b/src/conntrack/build.c
index 1bc87f9..8c7cb7f 100644
--- a/src/conntrack/build.c
+++ b/src/conntrack/build.c
@@ -308,6 +308,38 @@ void __build_secmark(struct nfnlhdr *req,
 	nfnl_addattr32(&req->nlh, size, CTA_SECMARK, htonl(ct->secmark));
 }
 
+const char *helper_id_to_name[] = {
+	[NFCT_HELPER_UNSPEC]		= "unknown-helper",
+	[NFCT_HELPER_AMANDA] 		= "amanda",
+	[NFCT_HELPER_FTP] 		= "ftp",
+	[NFCT_HELPER_H323]		= "h323",
+	[NFCT_HELPER_IRC]		= "irc",
+	[NFCT_HELPER_NETBIOS_NS]	= "netbios_ns",
+	[NFCT_HELPER_PPTP]		= "pptp",
+	[NFCT_HELPER_SANE]		= "sane",
+	[NFCT_HELPER_SIP]		= "sip",
+	[NFCT_HELPER_TFTP]		= "tftp",
+};
+
+void __build_helper_name(struct nfnlhdr *req,
+			 size_t size,
+			 const struct nf_conntrack *ct)
+{
+	struct nfattr *nest;
+
+	/* helper set, but probably unsupported */
+	if (ct->helper_id == 0)
+		return;
+
+	nest = nfnl_nest(&req->nlh, size, CTA_HELP);
+	nfnl_addattr_l(&req->nlh,
+			size, 
+			CTA_HELP_NAME,
+			helper_id_to_name[ct->helper_id],
+			strlen(helper_id_to_name[ct->helper_id]));
+	nfnl_nest_end(&req->nlh, nest);
+}
+
 int __build_conntrack(struct nfnl_subsys_handle *ssh,
 		      struct nfnlhdr *req,
 		      size_t size,
@@ -417,5 +449,8 @@ int __build_conntrack(struct nfnl_subsys_handle *ssh,
 	    test_bit(ATTR_REPL_NAT_SEQ_OFFSET_AFTER, ct->set))
 	    	__build_nat_seq_adj(req, size, ct, __DIR_REPL);
 
+	if (test_bit(ATTR_HELPER_ID, ct->set))
+		__build_helper_name(req, size, ct);
+
 	return 0;
 }
diff --git a/src/conntrack/getter.c b/src/conntrack/getter.c
index 20a2a35..65035f0 100644
--- a/src/conntrack/getter.c
+++ b/src/conntrack/getter.c
@@ -282,6 +282,11 @@ static const void *get_attr_repl_off_aft(const struct nf_conntrack *ct)
 	return &ct->tuple[__DIR_REPL].natseq.offset_after;
 }
 
+static const void *get_attr_helper_id(const struct nf_conntrack *ct)
+{
+	return &ct->helper_id;
+}
+
 get_attr get_attr_array[] = {
 	[ATTR_ORIG_IPV4_SRC]		= get_attr_orig_ipv4_src,
 	[ATTR_ORIG_IPV4_DST] 		= get_attr_orig_ipv4_dst,
@@ -338,4 +343,5 @@ get_attr get_attr_array[] = {
 	[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,
+	[ATTR_HELPER_ID]		= get_attr_helper_id,
 };
diff --git a/src/conntrack/parse.c b/src/conntrack/parse.c
index 11cf5ff..41c0c26 100644
--- a/src/conntrack/parse.c
+++ b/src/conntrack/parse.c
@@ -356,6 +356,31 @@ __parse_nat_seq(const struct nfattr *attr, struct nf_conntrack *ct, int dir)
 	}
 }
 
+static void 
+__parse_helper(const struct nfattr *attr, struct nf_conntrack *ct)
+{
+	int i, found = 0;
+	struct nfattr *tb[CTA_NAT_SEQ_MAX];
+
+	nfnl_parse_nested(tb, CTA_NAT_SEQ_MAX, attr);
+	if (!tb[CTA_HELP_NAME-1])
+		return;
+
+	for (i=0; i<NFCT_HELPER_MAX; i++) {
+		if (strcmp(NFA_DATA(tb[CTA_HELP_NAME-1]), 
+			   helper_id_to_name[i]) == 0) {
+			found = 1;
+			break;
+		}
+	}
+
+	if (!found)
+		return;
+
+	ct->helper_id = i;
+	set_bit(ATTR_HELPER_ID, ct->set);
+}
+
 int __parse_message_type(const struct nlmsghdr *nlh)
 {
 	u_int16_t type = NFNL_MSG_TYPE(nlh->nlmsg_type);
@@ -447,4 +472,7 @@ void __parse_conntrack(const struct nlmsghdr *nlh,
 		ct->id = ntohl(*(u_int32_t *)NFA_DATA(cda[CTA_ID-1]));
 		set_bit(ATTR_ID, ct->set);
 	}
+
+	if (cda[CTA_HELP-1])
+		__parse_helper(cda[CTA_HELP-1], ct);
 }
diff --git a/src/conntrack/setter.c b/src/conntrack/setter.c
index 6759652..b9e93ca 100644
--- a/src/conntrack/setter.c
+++ b/src/conntrack/setter.c
@@ -308,6 +308,16 @@ static void set_attr_repl_off_aft(struct nf_conntrack *ct, const void *value)
 	ct->tuple[__DIR_REPL].natseq.offset_after = *((u_int32_t *) value);
 }
 
+static void set_attr_helper_id(struct nf_conntrack *ct, const void *value)
+{
+	u_int32_t val = *((u_int32_t *)value);
+
+	if (val >= NFCT_HELPER_MAX)
+		val = 0;
+
+	ct->helper_id = val;
+}
+
 static void set_attr_do_nothing(struct nf_conntrack *ct, const void *value) {}
 
 set_attr set_attr_array[] = {
@@ -366,4 +376,5 @@ set_attr set_attr_array[] = {
 	[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,
+	[ATTR_HELPER_ID]	= set_attr_helper_id,
 };
diff --git a/utils/conntrack_create.c b/utils/conntrack_create.c
index bc591b5..04b9807 100644
--- a/utils/conntrack_create.c
+++ b/utils/conntrack_create.c
@@ -29,6 +29,7 @@ int main()
 
 	nfct_set_attr_u8(ct, ATTR_TCP_STATE, TCP_CONNTRACK_LISTEN);
 	nfct_set_attr_u32(ct, ATTR_TIMEOUT, 100);
+	nfct_set_attr_u32(ct, ATTR_HELPER_ID, NFCT_HELPER_FTP);
 
 	h = nfct_open(CONNTRACK, 0);
 	if (!h) {

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

  Powered by Linux