lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [thread-next>] [day] [month] [year] [list]
Message-Id: <1434554088-10200-1-git-send-email-kraig@google.com>
Date:	Wed, 17 Jun 2015 11:14:48 -0400
From:	Craig Gallek <kraig@...gle.com>
To:	netdev@...r.kernel.org
Cc:	stephen@...workplumber.org, edumazet@...gle.com,
	Craig Gallek <kraig@...gle.com>
Subject: [PATCH iproute2 v2] ss: Include -E option for socket destroy events

Use the IPv4/IPv6/TCP/UDP multicast groups of NETLINK_SOCK_DIAG
to filter and display socket statistics as they are destroyed.

Kernel support patch series: 24029a3603cfa633e8bc2b3fb3e48e76c497831d

Signed-off-by: Craig Gallek <kraig@...gle.com>
---
 include/linux/inet_diag.h |  3 +-
 include/linux/sock_diag.h | 10 +++++++
 misc/ss.c                 | 74 +++++++++++++++++++++++++++++++++++++++++++++--
 3 files changed, 84 insertions(+), 3 deletions(-)

diff --git a/include/linux/inet_diag.h b/include/linux/inet_diag.h
index 0fb76bb..e83340b 100644
--- a/include/linux/inet_diag.h
+++ b/include/linux/inet_diag.h
@@ -111,9 +111,10 @@ enum {
 	INET_DIAG_SKMEMINFO,
 	INET_DIAG_SHUTDOWN,
 	INET_DIAG_DCTCPINFO,
+	INET_DIAG_PROTOCOL,  /* response attribute only */
 };
 
-#define INET_DIAG_MAX INET_DIAG_DCTCPINFO
+#define INET_DIAG_MAX INET_DIAG_PROTOCOL
 
 /* INET_DIAG_MEM */
 
diff --git a/include/linux/sock_diag.h b/include/linux/sock_diag.h
index 78996e2..024e1f4 100644
--- a/include/linux/sock_diag.h
+++ b/include/linux/sock_diag.h
@@ -23,4 +23,14 @@ enum {
 	SK_MEMINFO_VARS,
 };
 
+enum sknetlink_groups {
+	SKNLGRP_NONE,
+	SKNLGRP_INET_TCP_DESTROY,
+	SKNLGRP_INET_UDP_DESTROY,
+	SKNLGRP_INET6_TCP_DESTROY,
+	SKNLGRP_INET6_UDP_DESTROY,
+	__SKNLGRP_MAX,
+};
+#define SKNLGRP_MAX	(__SKNLGRP_MAX - 1)
+
 #endif /* __SOCK_DIAG_H__ */
diff --git a/misc/ss.c b/misc/ss.c
index dba0901..759795c 100644
--- a/misc/ss.c
+++ b/misc/ss.c
@@ -99,6 +99,7 @@ int show_proc_ctx = 0;
 int show_sock_ctx = 0;
 /* If show_users & show_proc_ctx only do user_ent_hash_build() once */
 int user_ent_hash_build_init = 0;
+int follow_events = 0;
 
 int netid_width;
 int state_width;
@@ -2030,6 +2031,9 @@ static int inet_show_sock(struct nlmsghdr *nlh, struct filter *f, int protocol)
 	if (f && f->f && run_ssfilter(f->f, &s) == 0)
 		return 0;
 
+	if (tb[INET_DIAG_PROTOCOL])
+		protocol = *(__u8 *)RTA_DATA(tb[INET_DIAG_PROTOCOL]);
+
 	inet_stats_print(&s, protocol);
 
 	if (show_options) {
@@ -2201,7 +2205,7 @@ static int show_one_inet_sock(const struct sockaddr_nl *addr,
 
 	if (!(diag_arg->f->families & (1 << r->idiag_family)))
 		return 0;
-	if ((err = inet_show_sock(h, NULL, diag_arg->protocol)) < 0)
+	if ((err = inet_show_sock(h, diag_arg->f, diag_arg->protocol)) < 0)
 		return err;
 
 	return 0;
@@ -3217,6 +3221,64 @@ static int netlink_show(struct filter *f)
 	return 0;
 }
 
+struct sock_diag_msg {
+	__u8 sdiag_family;
+};
+
+static int generic_show_sock(const struct sockaddr_nl *addr,
+		struct nlmsghdr *nlh, void *arg)
+{
+	struct sock_diag_msg *r = NLMSG_DATA(nlh);
+	struct inet_diag_arg inet_arg = { .f = arg, .protocol = IPPROTO_MAX };
+
+	switch (r->sdiag_family) {
+	case AF_INET:
+	case AF_INET6:
+		return show_one_inet_sock(addr, nlh, &inet_arg);
+	case AF_UNIX:
+		return unix_show_sock(addr, nlh, arg);
+	case AF_PACKET:
+		return packet_show_sock(addr, nlh, arg);
+	case AF_NETLINK:
+		return netlink_show_sock(addr, nlh, arg);
+	default:
+		return -1;
+	}
+}
+
+static int handle_follow_request(struct filter *f)
+{
+	int ret = -1;
+	int groups = 0;
+	struct rtnl_handle rth;
+
+	if (f->families & (1 << AF_INET) && f->dbs & (1 << TCP_DB))
+		groups |= 1 << (SKNLGRP_INET_TCP_DESTROY - 1);
+	if (f->families & (1 << AF_INET) && f->dbs & (1 << UDP_DB))
+		groups |= 1 << (SKNLGRP_INET_UDP_DESTROY - 1);
+	if (f->families & (1 << AF_INET6) && f->dbs & (1 << TCP_DB))
+		groups |= 1 << (SKNLGRP_INET6_TCP_DESTROY - 1);
+	if (f->families & (1 << AF_INET6) && f->dbs & (1 << UDP_DB))
+		groups |= 1 << (SKNLGRP_INET6_UDP_DESTROY - 1);
+
+	if (groups == 0)
+		return -1;
+
+	if (rtnl_open_byproto(&rth, groups, NETLINK_SOCK_DIAG))
+		return -1;
+
+	rth.dump = 0;
+	rth.local.nl_pid = 0;
+
+	if (rtnl_dump_filter(&rth, generic_show_sock, f))
+		goto Exit;
+
+	ret = 0;
+Exit:
+	rtnl_close(&rth);
+	return ret;
+}
+
 struct snmpstat
 {
 	int tcp_estab;
@@ -3399,6 +3461,7 @@ static void _usage(FILE *dest)
 "   -i, --info          show internal TCP information\n"
 "   -s, --summary       show socket usage summary\n"
 "   -b, --bpf           show bpf filter socket information\n"
+"   -E, --events        continually display sockets as they are destroyed\n"
 "   -Z, --context       display process SELinux security contexts\n"
 "   -z, --contexts      display process and socket SELinux security contexts\n"
 "   -N, --net           switch to the specified network namespace name\n"
@@ -3481,6 +3544,7 @@ static const struct option long_opts[] = {
 	{ "info", 0, 0, 'i' },
 	{ "processes", 0, 0, 'p' },
 	{ "bpf", 0, 0, 'b' },
+	{ "events", 0, 0, 'E' },
 	{ "dccp", 0, 0, 'd' },
 	{ "tcp", 0, 0, 't' },
 	{ "udp", 0, 0, 'u' },
@@ -3516,7 +3580,7 @@ int main(int argc, char *argv[])
 	int ch;
 	int state_filter = 0;
 
-	while ((ch = getopt_long(argc, argv, "dhaletuwxnro460spbf:miA:D:F:vVzZN:",
+	while ((ch = getopt_long(argc, argv, "dhaletuwxnro460spbEf:miA:D:F:vVzZN:",
 				 long_opts, NULL)) != EOF) {
 		switch(ch) {
 		case 'n':
@@ -3546,6 +3610,9 @@ int main(int argc, char *argv[])
 			show_options = 1;
 			show_bpf++;
 			break;
+		case 'E':
+			follow_events = 1;
+			break;
 		case 'd':
 			filter_db_set(&current_filter, DCCP_DB);
 			break;
@@ -3838,6 +3905,9 @@ int main(int argc, char *argv[])
 
 	fflush(stdout);
 
+	if (follow_events)
+		exit(handle_follow_request(&current_filter));
+
 	if (current_filter.dbs & (1<<NETLINK_DB))
 		netlink_show(&current_filter);
 	if (current_filter.dbs & PACKET_DBM)
-- 
2.2.0.rc0.207.ga3a616c

--
To unsubscribe from this list: send the line "unsubscribe netdev" in
the body of a message to majordomo@...r.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ