netfilter-devel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH conntrack-tools 1/3] conntrack: extend nfct_mnl_socket_open() to use it to handle events
@ 2019-02-20 18:51 Pablo Neira Ayuso
  2019-02-20 18:51 ` [PATCH conntrack-tools 2/3] conntrack: use libmnl for conntrack events Pablo Neira Ayuso
  2019-02-20 18:51 ` [PATCH conntrack-tools 3/3] conntrack: add -o userspace option to tag user-triggered events Pablo Neira Ayuso
  0 siblings, 2 replies; 3+ messages in thread
From: Pablo Neira Ayuso @ 2019-02-20 18:51 UTC (permalink / raw)
  To: netfilter-devel

Add parameter to nfct_mnl_socket_open() to subscribe to events.

Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
---
 src/conntrack.c | 16 ++++++++--------
 1 file changed, 8 insertions(+), 8 deletions(-)

diff --git a/src/conntrack.c b/src/conntrack.c
index d638a6a2db9d..a5861cbb85ce 100644
--- a/src/conntrack.c
+++ b/src/conntrack.c
@@ -1848,14 +1848,14 @@ static struct nfct_mnl_socket {
 	uint32_t		portid;
 } sock;
 
-static int nfct_mnl_socket_open(void)
+static int nfct_mnl_socket_open(unsigned int events)
 {
 	sock.mnl = mnl_socket_open(NETLINK_NETFILTER);
 	if (sock.mnl == NULL) {
 		perror("mnl_socket_open");
 		return -1;
 	}
-	if (mnl_socket_bind(sock.mnl, 0, MNL_SOCKET_AUTOPID) < 0) {
+	if (mnl_socket_bind(sock.mnl, events, MNL_SOCKET_AUTOPID) < 0) {
 		perror("mnl_socket_bind");
 		return -1;
 	}
@@ -2566,7 +2566,7 @@ int main(int argc, char *argv[])
 
 	case CT_LIST:
 		if (type == CT_TABLE_DYING) {
-			if (nfct_mnl_socket_open() < 0)
+			if (nfct_mnl_socket_open(0) < 0)
 				exit_error(OTHER_PROBLEM, "Can't open handler");
 
 			res = nfct_mnl_dump(NFNL_SUBSYS_CTNETLINK,
@@ -2576,7 +2576,7 @@ int main(int argc, char *argv[])
 			nfct_mnl_socket_close();
 			break;
 		} else if (type == CT_TABLE_UNCONFIRMED) {
-			if (nfct_mnl_socket_open() < 0)
+			if (nfct_mnl_socket_open(0) < 0)
 				exit_error(OTHER_PROBLEM, "Can't open handler");
 
 			res = nfct_mnl_dump(NFNL_SUBSYS_CTNETLINK,
@@ -2779,7 +2779,7 @@ int main(int argc, char *argv[])
 		fprintf(stderr, "%s v%s (conntrack-tools): ",PROGNAME,VERSION);
 		fprintf(stderr,"expectation table has been emptied.\n");
 		break;
-		
+
 	case CT_EVENT:
 		if (options & CT_OPT_EVENT_MASK) {
 			unsigned int nl_events = 0;
@@ -2860,7 +2860,7 @@ int main(int argc, char *argv[])
 		/* If we fail with netlink, fall back to /proc to ensure
 		 * backward compatibility.
 		 */
-		if (nfct_mnl_socket_open() < 0)
+		if (nfct_mnl_socket_open(0) < 0)
 			goto try_proc_count;
 
 		res = nfct_mnl_get(NFNL_SUBSYS_CTNETLINK,
@@ -2905,7 +2905,7 @@ try_proc_count:
 		/* If we fail with netlink, fall back to /proc to ensure
 		 * backward compatibility.
 		 */
-		if (nfct_mnl_socket_open() < 0)
+		if (nfct_mnl_socket_open(0) < 0)
 			goto try_proc;
 
 		res = nfct_mnl_dump(NFNL_SUBSYS_CTNETLINK,
@@ -2924,7 +2924,7 @@ try_proc_count:
 		/* If we fail with netlink, fall back to /proc to ensure
 		 * backward compatibility.
 		 */
-		if (nfct_mnl_socket_open() < 0)
+		if (nfct_mnl_socket_open(0) < 0)
 			goto try_proc;
 
 		res = nfct_mnl_dump(NFNL_SUBSYS_CTNETLINK_EXP,
-- 
2.11.0


^ permalink raw reply related	[flat|nested] 3+ messages in thread

* [PATCH conntrack-tools 2/3] conntrack: use libmnl for conntrack events
  2019-02-20 18:51 [PATCH conntrack-tools 1/3] conntrack: extend nfct_mnl_socket_open() to use it to handle events Pablo Neira Ayuso
@ 2019-02-20 18:51 ` Pablo Neira Ayuso
  2019-02-20 18:51 ` [PATCH conntrack-tools 3/3] conntrack: add -o userspace option to tag user-triggered events Pablo Neira Ayuso
  1 sibling, 0 replies; 3+ messages in thread
From: Pablo Neira Ayuso @ 2019-02-20 18:51 UTC (permalink / raw)
  To: netfilter-devel

Use libmnl instead libnfnetlink infrastructure.

Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
---
 src/conntrack.c | 120 +++++++++++++++++++++++++++++++++++++++-----------------
 1 file changed, 83 insertions(+), 37 deletions(-)

diff --git a/src/conntrack.c b/src/conntrack.c
index a5861cbb85ce..e3abe9ff698e 100644
--- a/src/conntrack.c
+++ b/src/conntrack.c
@@ -64,6 +64,11 @@
 #include <libmnl/libmnl.h>
 #include <libnetfilter_conntrack/libnetfilter_conntrack.h>
 
+static struct nfct_mnl_socket {
+	struct mnl_socket	*mnl;
+	uint32_t		portid;
+} sock;
+
 struct u32_mask {
 	uint32_t value;
 	uint32_t mask;
@@ -1397,7 +1402,7 @@ event_sighandler(int s)
 
 	fprintf(stderr, "%s v%s (conntrack-tools): ", PROGNAME, VERSION);
 	fprintf(stderr, "%d flow events have been shown.\n", counter);
-	nfct_close(cth);
+	mnl_socket_close(sock.mnl);
 	exit(0);
 }
 
@@ -1415,17 +1420,40 @@ exp_event_sighandler(int s)
 	exit(0);
 }
 
-static int event_cb(enum nf_conntrack_msg_type type,
-		    struct nf_conntrack *ct,
-		    void *data)
+static int event_cb(const struct nlmsghdr *nlh, void *data)
 {
-	char buf[1024];
-	struct nf_conntrack *obj = data;
 	unsigned int op_type = NFCT_O_DEFAULT;
+	struct nf_conntrack *obj = data;
+	enum nf_conntrack_msg_type type;
 	unsigned int op_flags = 0;
+	struct nf_conntrack *ct;
+	char buf[1024];
+
+	switch(nlh->nlmsg_type & 0xff) {
+	case IPCTNL_MSG_CT_NEW:
+		if (nlh->nlmsg_flags & NLM_F_CREATE)
+			type = NFCT_T_NEW;
+		else
+			type = NFCT_T_UPDATE;
+		break;
+	case IPCTNL_MSG_CT_DELETE:
+		type = NFCT_T_DESTROY;
+		break;
+	default:
+		/* Unknown event type. */
+		type = 0;
+		break;
+	}
+
+	ct = nfct_new();
+	if (!ct)
+		goto out;
+
+	if (nfct_nlmsg_parse(nlh, ct) < 0)
+		goto out;
 
 	if (nfct_filter(obj, ct))
-		return NFCT_CB_CONTINUE;
+		goto out;
 
 	if (output_mask & _O_XML) {
 		op_type = NFCT_O_XML;
@@ -1434,7 +1462,7 @@ static int event_cb(enum nf_conntrack_msg_type type,
 			printf("<?xml version=\"1.0\" encoding=\"utf-8\"?>\n"
 			       "<conntrack>\n");
 		}
-	} 
+	}
 	if (output_mask & _O_EXT)
 		op_flags = NFCT_OF_SHOW_LAYER3;
 	if (output_mask & _O_TMS) {
@@ -1456,8 +1484,9 @@ static int event_cb(enum nf_conntrack_msg_type type,
 	fflush(stdout);
 
 	counter++;
-
-	return NFCT_CB_CONTINUE;
+out:
+	nfct_destroy(ct);
+	return MNL_CB_OK;
 }
 
 static int dump_cb(enum nf_conntrack_msg_type type,
@@ -1843,11 +1872,6 @@ out_err:
 	return ret;
 }
 
-static struct nfct_mnl_socket {
-	struct mnl_socket	*mnl;
-	uint32_t		portid;
-} sock;
-
 static int nfct_mnl_socket_open(unsigned int events)
 {
 	sock.mnl = mnl_socket_open(NETLINK_NETFILTER);
@@ -2791,42 +2815,64 @@ int main(int argc, char *argv[])
 			if (event_mask & CT_EVENT_F_DEL)
 				nl_events |= NF_NETLINK_CONNTRACK_DESTROY;
 
-			cth = nfct_open(CONNTRACK, nl_events);
+			res = nfct_mnl_socket_open(nl_events);
 		} else {
-			cth = nfct_open(CONNTRACK,
-					NF_NETLINK_CONNTRACK_NEW |
-					NF_NETLINK_CONNTRACK_UPDATE |
-					NF_NETLINK_CONNTRACK_DESTROY);
+			res = nfct_mnl_socket_open(NF_NETLINK_CONNTRACK_NEW |
+						   NF_NETLINK_CONNTRACK_UPDATE |
+						   NF_NETLINK_CONNTRACK_DESTROY);
 		}
 
-		if (!cth)
-			exit_error(OTHER_PROBLEM, "Can't open handler");
+		if (res < 0)
+			exit_error(OTHER_PROBLEM, "Can't open netlink socket");
 
 		if (options & CT_OPT_BUFFERSIZE) {
-			size_t ret;
-			ret = nfnl_rcvbufsiz(nfct_nfnlh(cth), socketbuffersize);
+			socklen_t socklen = sizeof(socketbuffersize);
+
+			res = setsockopt(mnl_socket_get_fd(sock.mnl),
+					 SOL_SOCKET, SO_RCVBUFFORCE,
+					 &socketbuffersize,
+					 sizeof(socketbuffersize));
+			if (res < 0) {
+				setsockopt(mnl_socket_get_fd(sock.mnl),
+					   SOL_SOCKET, SO_RCVBUF,
+					   &socketbuffersize,
+					   socketbuffersize);
+			}
+			getsockopt(mnl_socket_get_fd(sock.mnl), SOL_SOCKET,
+				   SO_RCVBUF, &socketbuffersize, &socklen);
 			fprintf(stderr, "NOTICE: Netlink socket buffer size "
-					"has been set to %zu bytes.\n", ret);
+					"has been set to %zu bytes.\n",
+					socketbuffersize);
 		}
 
 		nfct_filter_init(family);
 
 		signal(SIGINT, event_sighandler);
 		signal(SIGTERM, event_sighandler);
-		nfct_callback_register(cth, NFCT_T_ALL, event_cb, tmpl.ct);
-		res = nfct_catch(cth);
-		if (res == -1) {
-			if (errno == ENOBUFS) {
-				fprintf(stderr, 
-					"WARNING: We have hit ENOBUFS! We "
-					"are losing events.\nThis message "
-					"means that the current netlink "
-					"socket buffer size is too small.\n"
-					"Please, check --buffer-size in "
-					"conntrack(8) manpage.\n");
+
+		while (1) {
+			char buf[MNL_SOCKET_BUFFER_SIZE];
+
+			res = mnl_socket_recvfrom(sock.mnl, buf, sizeof(buf));
+			if (res < 0) {
+				if (errno == ENOBUFS) {
+					fprintf(stderr,
+						"WARNING: We have hit ENOBUFS! We "
+						"are losing events.\nThis message "
+						"means that the current netlink "
+						"socket buffer size is too small.\n"
+						"Please, check --buffer-size in "
+						"conntrack(8) manpage.\n");
+					continue;
+				}
+				exit_error(OTHER_PROBLEM,
+					   "failed to received netlink event: %s",
+					   strerror(errno));
+				break;
 			}
+			res = mnl_cb_run(buf, res, 0, 0, event_cb, tmpl.ct);
 		}
-		nfct_close(cth);
+		mnl_socket_close(sock.mnl);
 		break;
 
 	case EXP_EVENT:
-- 
2.11.0


^ permalink raw reply related	[flat|nested] 3+ messages in thread

* [PATCH conntrack-tools 3/3] conntrack: add -o userspace option to tag user-triggered events
  2019-02-20 18:51 [PATCH conntrack-tools 1/3] conntrack: extend nfct_mnl_socket_open() to use it to handle events Pablo Neira Ayuso
  2019-02-20 18:51 ` [PATCH conntrack-tools 2/3] conntrack: use libmnl for conntrack events Pablo Neira Ayuso
@ 2019-02-20 18:51 ` Pablo Neira Ayuso
  1 sibling, 0 replies; 3+ messages in thread
From: Pablo Neira Ayuso @ 2019-02-20 18:51 UTC (permalink / raw)
  To: netfilter-devel

The following command:

 # conntrack -E -o userspace &
 # conntrack -F
 [DESTROY] tcp      6 src=122.127.186.172 dst=192.168.10.195 sport=443 dport=48232 packets=56 bytes=5313 src=192.168.10.195 dst=122.127.186.172 sport=48232 dport=443 packets=49 bytes=5174 [ASSURED] [USERSPACE]

prints the [USERSPACE] tag at the end of the event, this tells users if
this event has been triggered by process, eg. via conntrack command
invocation.

Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
---
 conntrack.8     |  3 ++-
 src/conntrack.c | 19 ++++++++++++++-----
 2 files changed, 16 insertions(+), 6 deletions(-)

diff --git a/conntrack.8 b/conntrack.8
index e069dfe3809e..3c1e960e910e 100644
--- a/conntrack.8
+++ b/conntrack.8
@@ -109,13 +109,14 @@ Show the in-kernel connection tracking system statistics.
 Atomically zero counters after reading them.  This option is only valid in
 combination with the "\-L, \-\-dump" command options.
 .TP
-.BI "-o, --output [extended,xml,timestamp,id,ktimestamp,labels] "
+.BI "-o, --output [extended,xml,timestamp,id,ktimestamp,labels,userspace] "
 Display output in a certain format. With the extended output option, this tool
 displays the layer 3 information. With ktimestamp, it displays the in-kernel
 timestamp available since 2.6.38 (you can enable it via the \fBsysctl(8)\fP
 key \fBnet.netfilter.nf_conntrack_timestamp\fP).
 The labels output option tells \fBconntrack\fP to show the names of connection
 tracking labels that might be present.
+The userspace output options tells if the event has been triggered by a process.
 .TP
 .BI "-e, --event-mask " "[ALL|NEW|UPDATES|DESTROY][,...]"
 Set the bitmask of events that are to be generated by the in-kernel ctnetlink
diff --git a/src/conntrack.c b/src/conntrack.c
index e3abe9ff698e..daa93dbbdfe2 100644
--- a/src/conntrack.c
+++ b/src/conntrack.c
@@ -854,6 +854,7 @@ enum {
 	_O_ID	= (1 << 3),
 	_O_KTMS	= (1 << 4),
 	_O_CL	= (1 << 5),
+	_O_US	= (1 << 6),
 };
 
 enum {
@@ -864,16 +865,16 @@ enum {
 };
 
 static struct parse_parameter {
-	const char	*parameter[6];
+	const char	*parameter[7];
 	size_t  size;
-	unsigned int value[6];
+	unsigned int value[7];
 } parse_array[PARSE_MAX] = {
 	{ {"ASSURED", "SEEN_REPLY", "UNSET", "FIXED_TIMEOUT", "EXPECTED"}, 5,
 	  { IPS_ASSURED, IPS_SEEN_REPLY, 0, IPS_FIXED_TIMEOUT, IPS_EXPECTED} },
 	{ {"ALL", "NEW", "UPDATES", "DESTROY"}, 4,
 	  { CT_EVENT_F_ALL, CT_EVENT_F_NEW, CT_EVENT_F_UPD, CT_EVENT_F_DEL } },
-	{ {"xml", "extended", "timestamp", "id", "ktimestamp", "labels", }, 6,
-	  { _O_XML, _O_EXT, _O_TMS, _O_ID, _O_KTMS, _O_CL },
+	{ {"xml", "extended", "timestamp", "id", "ktimestamp", "labels", "userspace" }, 7,
+	  { _O_XML, _O_EXT, _O_TMS, _O_ID, _O_KTMS, _O_CL, _O_US },
 	},
 };
 
@@ -1427,6 +1428,7 @@ static int event_cb(const struct nlmsghdr *nlh, void *data)
 	enum nf_conntrack_msg_type type;
 	unsigned int op_flags = 0;
 	struct nf_conntrack *ct;
+	bool userspace = false;
 	char buf[1024];
 
 	switch(nlh->nlmsg_type & 0xff) {
@@ -1480,7 +1482,14 @@ static int event_cb(const struct nlmsghdr *nlh, void *data)
 
 	nfct_snprintf_labels(buf, sizeof(buf), ct, type, op_type, op_flags, labelmap);
 
-	printf("%s\n", buf);
+	if (output_mask & _O_US) {
+		if (nlh->nlmsg_pid)
+			userspace = true;
+		else
+			userspace = false;
+	}
+
+	printf("%s%s\n", buf, userspace ? " [USERSPACE]" : "");
 	fflush(stdout);
 
 	counter++;
-- 
2.11.0


^ permalink raw reply related	[flat|nested] 3+ messages in thread

end of thread, other threads:[~2019-02-20 18:51 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2019-02-20 18:51 [PATCH conntrack-tools 1/3] conntrack: extend nfct_mnl_socket_open() to use it to handle events Pablo Neira Ayuso
2019-02-20 18:51 ` [PATCH conntrack-tools 2/3] conntrack: use libmnl for conntrack events Pablo Neira Ayuso
2019-02-20 18:51 ` [PATCH conntrack-tools 3/3] conntrack: add -o userspace option to tag user-triggered events Pablo Neira Ayuso

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).