naccyde / rpms / iproute

Forked from rpms/iproute a year ago
Clone

Blame SOURCES/0006-ss-Add-support-for-SCTP-protocol.patch

4aca6e
From 48d997511c1537ec8e2d6227251f8be1ede064d4 Mon Sep 17 00:00:00 2001
4aca6e
From: Phil Sutter <psutter@redhat.com>
4aca6e
Date: Wed, 1 Feb 2017 12:10:00 +0100
4aca6e
Subject: [PATCH] ss: Add support for SCTP protocol
4aca6e
4aca6e
Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=1063934
4aca6e
Upstream Status: iproute2.git commit f89d46ad63f6f
4aca6e
Conflicts:
4aca6e
* missing commit 6885e3bf8efa3
4aca6e
  ("ss: Include -E option for socket destroy events")
4aca6e
* missing commit acd1e437befbb ("misc: fix style issues")
4aca6e
* missing commit 82d73ea03a149 ("ss: Refactor inet_show_sock")
4aca6e
* missing other commandline flags/features
4aca6e
* fixed for missing commit a418e451643e7
4aca6e
  ("make format_host non-reentrant by default")
4aca6e
4aca6e
commit f89d46ad63f6f606f777da964205bc53b2197cfa
4aca6e
Author: Phil Sutter <phil@nwl.cc>
4aca6e
Date:   Wed Nov 9 12:12:24 2016 +0100
4aca6e
4aca6e
    ss: Add support for SCTP protocol
4aca6e
4aca6e
    This makes use of the sctp_diag interface recently added to the kernel.
4aca6e
4aca6e
    Joint work with Xin Long who provided the PoC implementation which I
4aca6e
    merely polished up a bit.
4aca6e
4aca6e
    Signed-off-by: Phil Sutter <phil@nwl.cc>
4aca6e
---
4aca6e
 man/man8/ss.8 |   3 +
4aca6e
 misc/ss.c     | 215 +++++++++++++++++++++++++++++++++++++++++++++++++++++++---
4aca6e
 2 files changed, 210 insertions(+), 8 deletions(-)
4aca6e
4aca6e
diff --git a/man/man8/ss.8 b/man/man8/ss.8
4aca6e
index f4d5264..b02a68c 100644
4aca6e
--- a/man/man8/ss.8
4aca6e
+++ b/man/man8/ss.8
4aca6e
@@ -114,6 +114,9 @@ Display RAW sockets.
4aca6e
 .B \-x, \-\-unix
4aca6e
 Display Unix domain sockets (alias for -f unix).
4aca6e
 .TP
4aca6e
+.B \-S, \-\-sctp
4aca6e
+Display SCTP sockets.
4aca6e
+.TP
4aca6e
 .B \-f FAMILY, \-\-family=FAMILY
4aca6e
 Display sockets of type FAMILY.
4aca6e
 Currently the following families are supported: unix, inet, inet6, link, netlink.
4aca6e
diff --git a/misc/ss.c b/misc/ss.c
4aca6e
index 45fb4b0..d438428 100644
4aca6e
--- a/misc/ss.c
4aca6e
+++ b/misc/ss.c
4aca6e
@@ -42,6 +42,7 @@
4aca6e
 #include <linux/filter.h>
4aca6e
 #include <linux/packet_diag.h>
4aca6e
 #include <linux/netlink_diag.h>
4aca6e
+#include <linux/sctp.h>
4aca6e
 
4aca6e
 #define MAGIC_SEQ 123456
4aca6e
 
4aca6e
@@ -99,6 +100,7 @@ int show_proc_ctx = 0;
4aca6e
 int show_sock_ctx = 0;
4aca6e
 /* If show_users & show_proc_ctx only do user_ent_hash_build() once */
4aca6e
 int user_ent_hash_build_init = 0;
4aca6e
+int sctp_ino;
4aca6e
 
4aca6e
 int netid_width;
4aca6e
 int state_width;
4aca6e
@@ -108,6 +110,7 @@ int serv_width;
4aca6e
 int screen_width;
4aca6e
 
4aca6e
 static const char *TCP_PROTO = "tcp";
4aca6e
+static const char *SCTP_PROTO = "sctp";
4aca6e
 static const char *UDP_PROTO = "udp";
4aca6e
 static const char *RAW_PROTO = "raw";
4aca6e
 static const char *dg_proto = NULL;
4aca6e
@@ -124,13 +127,14 @@ enum
4aca6e
 	PACKET_DG_DB,
4aca6e
 	PACKET_R_DB,
4aca6e
 	NETLINK_DB,
4aca6e
+	SCTP_DB,
4aca6e
 	MAX_DB
4aca6e
 };
4aca6e
 
4aca6e
 #define PACKET_DBM ((1<
4aca6e
 #define UNIX_DBM ((1<
4aca6e
 #define ALL_DB ((1<
4aca6e
-#define INET_DBM ((1<
4aca6e
+#define INET_DBM ((1<
4aca6e
 
4aca6e
 enum {
4aca6e
 	SS_UNKNOWN,
4aca6e
@@ -148,6 +152,17 @@ enum {
4aca6e
 	SS_MAX
4aca6e
 };
4aca6e
 
4aca6e
+enum {
4aca6e
+	SCTP_STATE_CLOSED		= 0,
4aca6e
+	SCTP_STATE_COOKIE_WAIT		= 1,
4aca6e
+	SCTP_STATE_COOKIE_ECHOED	= 2,
4aca6e
+	SCTP_STATE_ESTABLISHED		= 3,
4aca6e
+	SCTP_STATE_SHUTDOWN_PENDING	= 4,
4aca6e
+	SCTP_STATE_SHUTDOWN_SENT	= 5,
4aca6e
+	SCTP_STATE_SHUTDOWN_RECEIVED	= 6,
4aca6e
+	SCTP_STATE_SHUTDOWN_ACK_SENT	= 7,
4aca6e
+};
4aca6e
+
4aca6e
 #define SS_ALL ((1 << SS_MAX) - 1)
4aca6e
 #define SS_CONN (SS_ALL & ~((1<
4aca6e
 
4aca6e
@@ -202,6 +217,10 @@ static const struct filter default_dbs[MAX_DB] = {
4aca6e
 		.states   = (1 << SS_CLOSE),
4aca6e
 		.families = (1 << AF_NETLINK),
4aca6e
 	},
4aca6e
+	[SCTP_DB] = {
4aca6e
+		.states   = SS_CONN,
4aca6e
+		.families = (1 << AF_INET) | (1 << AF_INET6),
4aca6e
+	},
4aca6e
 };
4aca6e
 
4aca6e
 static const struct filter default_afs[AF_MAX] = {
4aca6e
@@ -262,6 +281,7 @@ static void filter_default_dbs(struct filter *f)
4aca6e
 	filter_db_set(f, PACKET_R_DB);
4aca6e
 	filter_db_set(f, PACKET_DG_DB);
4aca6e
 	filter_db_set(f, NETLINK_DB);
4aca6e
+	filter_db_set(f, SCTP_DB);
4aca6e
 }
4aca6e
 
4aca6e
 static void filter_states_set(struct filter *f, int states)
4aca6e
@@ -709,6 +729,17 @@ static const char *sstate_name[] = {
4aca6e
 	[SS_CLOSING] = "CLOSING",
4aca6e
 };
4aca6e
 
4aca6e
+static const char *sctp_sstate_name[] = {
4aca6e
+	[SCTP_STATE_CLOSED] = "CLOSED",
4aca6e
+	[SCTP_STATE_COOKIE_WAIT] = "COOKIE_WAIT",
4aca6e
+	[SCTP_STATE_COOKIE_ECHOED] = "COOKIE_ECHOED",
4aca6e
+	[SCTP_STATE_ESTABLISHED] = "ESTAB",
4aca6e
+	[SCTP_STATE_SHUTDOWN_PENDING] = "SHUTDOWN_PENDING",
4aca6e
+	[SCTP_STATE_SHUTDOWN_SENT] = "SHUTDOWN_SENT",
4aca6e
+	[SCTP_STATE_SHUTDOWN_RECEIVED] = "SHUTDOWN_RECEIVED",
4aca6e
+	[SCTP_STATE_SHUTDOWN_ACK_SENT] = "ACK_SENT",
4aca6e
+};
4aca6e
+
4aca6e
 static const char *sstate_namel[] = {
4aca6e
 	"UNKNOWN",
4aca6e
 	[SS_ESTABLISHED] = "established",
4aca6e
@@ -792,12 +823,30 @@ struct tcpstat
4aca6e
 	struct dctcpstat    *dctcp;
4aca6e
 };
4aca6e
 
4aca6e
+/* SCTP assocs share the same inode number with their parent endpoint. So if we
4aca6e
+ * have seen the inode number before, it must be an assoc instead of the next
4aca6e
+ * endpoint. */
4aca6e
+static bool is_sctp_assoc(struct sockstat *s, const char *sock_name)
4aca6e
+{
4aca6e
+	if (strcmp(sock_name, "sctp"))
4aca6e
+		return false;
4aca6e
+	if (!sctp_ino || sctp_ino != s->ino)
4aca6e
+		return false;
4aca6e
+	return true;
4aca6e
+}
4aca6e
+
4aca6e
 static void sock_state_print(struct sockstat *s, const char *sock_name)
4aca6e
 {
4aca6e
 	if (netid_width)
4aca6e
-		printf("%-*s ", netid_width, sock_name);
4aca6e
-	if (state_width)
4aca6e
-		printf("%-*s ", state_width, sstate_name[s->state]);
4aca6e
+		printf("%-*s ", netid_width,
4aca6e
+		       is_sctp_assoc(s, sock_name) ? "" : sock_name);
4aca6e
+	if (state_width) {
4aca6e
+		if (is_sctp_assoc(s, sock_name))
4aca6e
+			printf("`- %-*s ", state_width - 3,
4aca6e
+			       sctp_sstate_name[s->state]);
4aca6e
+		else
4aca6e
+			printf("%-*s ", state_width, sstate_name[s->state]);
4aca6e
+	}
4aca6e
 
4aca6e
 	printf("%-6d %-6d ", s->rq, s->wq);
4aca6e
 }
4aca6e
@@ -895,6 +944,8 @@ static void init_service_resolver(void)
4aca6e
 						c->proto = TCP_PROTO;
4aca6e
 					else if (strcmp(proto, UDP_PROTO) == 0)
4aca6e
 						c->proto = UDP_PROTO;
4aca6e
+					else if (strcmp(proto, SCTP_PROTO) == 0)
4aca6e
+						c->proto = SCTP_PROTO;
4aca6e
 					else
4aca6e
 						c->proto = NULL;
4aca6e
 					c->next = rlist;
4aca6e
@@ -1566,6 +1617,8 @@ static char *proto_name(int protocol)
4aca6e
 		return "udp";
4aca6e
 	case IPPROTO_TCP:
4aca6e
 		return "tcp";
4aca6e
+	case IPPROTO_SCTP:
4aca6e
+		return "sctp";
4aca6e
 	case IPPROTO_DCCP:
4aca6e
 		return "dccp";
4aca6e
 	}
4aca6e
@@ -1658,6 +1711,56 @@ static char *sprint_bw(char *buf, double bw)
4aca6e
 	return buf;
4aca6e
 }
4aca6e
 
4aca6e
+static void sctp_stats_print(struct sctp_info *s)
4aca6e
+{
4aca6e
+	if (s->sctpi_tag)
4aca6e
+		printf(" tag:%x", s->sctpi_tag);
4aca6e
+	if (s->sctpi_state)
4aca6e
+		printf(" state:%s", sctp_sstate_name[s->sctpi_state]);
4aca6e
+	if (s->sctpi_rwnd)
4aca6e
+		printf(" rwnd:%d", s->sctpi_rwnd);
4aca6e
+	if (s->sctpi_unackdata)
4aca6e
+		printf(" unackdata:%d", s->sctpi_unackdata);
4aca6e
+	if (s->sctpi_penddata)
4aca6e
+		printf(" penddata:%d", s->sctpi_penddata);
4aca6e
+	if (s->sctpi_instrms)
4aca6e
+		printf(" instrms:%d", s->sctpi_instrms);
4aca6e
+	if (s->sctpi_outstrms)
4aca6e
+		printf(" outstrms:%d", s->sctpi_outstrms);
4aca6e
+	if (s->sctpi_inqueue)
4aca6e
+		printf(" inqueue:%d", s->sctpi_inqueue);
4aca6e
+	if (s->sctpi_outqueue)
4aca6e
+		printf(" outqueue:%d", s->sctpi_outqueue);
4aca6e
+	if (s->sctpi_overall_error)
4aca6e
+		printf(" overerr:%d", s->sctpi_overall_error);
4aca6e
+	if (s->sctpi_max_burst)
4aca6e
+		printf(" maxburst:%d", s->sctpi_max_burst);
4aca6e
+	if (s->sctpi_maxseg)
4aca6e
+		printf(" maxseg:%d", s->sctpi_maxseg);
4aca6e
+	if (s->sctpi_peer_rwnd)
4aca6e
+		printf(" prwnd:%d", s->sctpi_peer_rwnd);
4aca6e
+	if (s->sctpi_peer_tag)
4aca6e
+		printf(" ptag:%x", s->sctpi_peer_tag);
4aca6e
+	if (s->sctpi_peer_capable)
4aca6e
+		printf(" pcapable:%d", s->sctpi_peer_capable);
4aca6e
+	if (s->sctpi_peer_sack)
4aca6e
+		printf(" psack:%d", s->sctpi_peer_sack);
4aca6e
+	if (s->sctpi_s_autoclose)
4aca6e
+		printf(" autoclose:%d", s->sctpi_s_autoclose);
4aca6e
+	if (s->sctpi_s_adaptation_ind)
4aca6e
+		printf(" adapind:%d", s->sctpi_s_adaptation_ind);
4aca6e
+	if (s->sctpi_s_pd_point)
4aca6e
+		printf(" pdpoint:%d", s->sctpi_s_pd_point);
4aca6e
+	if (s->sctpi_s_nodelay)
4aca6e
+		printf(" nodealy:%d", s->sctpi_s_nodelay);
4aca6e
+	if (s->sctpi_s_disable_fragments)
4aca6e
+		printf(" nofrag:%d", s->sctpi_s_disable_fragments);
4aca6e
+	if (s->sctpi_s_v4mapped)
4aca6e
+		printf(" v4mapped:%d", s->sctpi_s_v4mapped);
4aca6e
+	if (s->sctpi_s_frag_interleave)
4aca6e
+		printf(" fraginl:%d", s->sctpi_s_frag_interleave);
4aca6e
+}
4aca6e
+
4aca6e
 static void tcp_stats_print(struct tcpstat *s)
4aca6e
 {
4aca6e
 	char b1[64];
4aca6e
@@ -1762,6 +1865,13 @@ static void tcp_timer_print(struct tcpstat *s)
4aca6e
 	}
4aca6e
 }
4aca6e
 
4aca6e
+static void sctp_timer_print(struct tcpstat *s)
4aca6e
+{
4aca6e
+	if (s->timer)
4aca6e
+		printf(" timer:(T3_RTX,%s,%d)",
4aca6e
+		       print_ms_timer(s->timeout), s->retrans);
4aca6e
+}
4aca6e
+
4aca6e
 static int tcp_show_line(char *line, const struct filter *f, int family)
4aca6e
 {
4aca6e
 	int rto = 0, ato = 0;
4aca6e
@@ -2007,6 +2117,67 @@ static void tcp_show_info(const struct nlmsghdr *nlh, struct inet_diag_msg *r,
4aca6e
 	}
4aca6e
 }
4aca6e
 
4aca6e
+static const char *format_host_sa(struct sockaddr_storage *sa)
4aca6e
+{
4aca6e
+	char buf[1024];
4aca6e
+	union {
4aca6e
+		struct sockaddr_in sin;
4aca6e
+		struct sockaddr_in6 sin6;
4aca6e
+	} *saddr = (void *)sa;
4aca6e
+
4aca6e
+	switch (sa->ss_family) {
4aca6e
+	case AF_INET:
4aca6e
+		return format_host(AF_INET, 4, &saddr->sin.sin_addr,
4aca6e
+				   buf, sizeof(buf));
4aca6e
+	case AF_INET6:
4aca6e
+		return format_host(AF_INET6, 16, &saddr->sin6.sin6_addr,
4aca6e
+				   buf, sizeof(buf));
4aca6e
+	default:
4aca6e
+		return "";
4aca6e
+	}
4aca6e
+}
4aca6e
+
4aca6e
+static void sctp_show_info(const struct nlmsghdr *nlh, struct inet_diag_msg *r,
4aca6e
+		struct rtattr *tb[])
4aca6e
+{
4aca6e
+	struct sockaddr_storage *sa;
4aca6e
+	int len;
4aca6e
+
4aca6e
+	print_skmeminfo(tb, INET_DIAG_SKMEMINFO);
4aca6e
+
4aca6e
+	if (tb[INET_DIAG_LOCALS]) {
4aca6e
+		len = RTA_PAYLOAD(tb[INET_DIAG_LOCALS]);
4aca6e
+		sa = RTA_DATA(tb[INET_DIAG_LOCALS]);
4aca6e
+
4aca6e
+		printf("locals:%s", format_host_sa(sa));
4aca6e
+		for (sa++, len -= sizeof(*sa); len > 0; sa++, len -= sizeof(*sa))
4aca6e
+			printf(",%s", format_host_sa(sa));
4aca6e
+
4aca6e
+	}
4aca6e
+	if (tb[INET_DIAG_PEERS]) {
4aca6e
+		len = RTA_PAYLOAD(tb[INET_DIAG_PEERS]);
4aca6e
+		sa = RTA_DATA(tb[INET_DIAG_PEERS]);
4aca6e
+
4aca6e
+		printf(" peers:%s", format_host_sa(sa));
4aca6e
+		for (sa++, len -= sizeof(*sa); len > 0; sa++, len -= sizeof(*sa))
4aca6e
+			printf(",%s", format_host_sa(sa));
4aca6e
+	}
4aca6e
+	if (tb[INET_DIAG_INFO]) {
4aca6e
+		struct sctp_info *info;
4aca6e
+		len = RTA_PAYLOAD(tb[INET_DIAG_INFO]);
4aca6e
+
4aca6e
+		/* workaround for older kernels with less fields */
4aca6e
+		if (len < sizeof(*info)) {
4aca6e
+			info = alloca(sizeof(*info));
4aca6e
+			memcpy(info, RTA_DATA(tb[INET_DIAG_INFO]), len);
4aca6e
+			memset((char *)info + len, 0, sizeof(*info) - len);
4aca6e
+		} else
4aca6e
+			info = RTA_DATA(tb[INET_DIAG_INFO]);
4aca6e
+
4aca6e
+		sctp_stats_print(info);
4aca6e
+	}
4aca6e
+}
4aca6e
+
4aca6e
 static int inet_show_sock(struct nlmsghdr *nlh, struct filter *f, int protocol)
4aca6e
 {
4aca6e
 	struct rtattr * tb[INET_DIAG_MAX+1];
4aca6e
@@ -2047,7 +2218,10 @@ static int inet_show_sock(struct nlmsghdr *nlh, struct filter *f, int protocol)
4aca6e
 		t.timer = r->idiag_timer;
4aca6e
 		t.timeout = r->idiag_expires;
4aca6e
 		t.retrans = r->idiag_retrans;
4aca6e
-		tcp_timer_print(&t);
4aca6e
+		if (protocol == IPPROTO_SCTP)
4aca6e
+			sctp_timer_print(&t);
4aca6e
+		else
4aca6e
+			tcp_timer_print(&t);
4aca6e
 	}
4aca6e
 
4aca6e
 	if (show_details) {
4aca6e
@@ -2066,8 +2240,12 @@ static int inet_show_sock(struct nlmsghdr *nlh, struct filter *f, int protocol)
4aca6e
 
4aca6e
 	if (show_mem || show_tcpinfo) {
4aca6e
 		printf("\n\t");
4aca6e
-		tcp_show_info(nlh, r, tb);
4aca6e
+		if (protocol == IPPROTO_SCTP)
4aca6e
+			sctp_show_info(nlh, r, tb);
4aca6e
+		else
4aca6e
+			tcp_show_info(nlh, r, tb);
4aca6e
 	}
4aca6e
+	sctp_ino = s.ino;
4aca6e
 
4aca6e
 	printf("\n");
4aca6e
 	return 0;
4aca6e
@@ -2392,6 +2570,17 @@ outerr:
4aca6e
 	} while (0);
4aca6e
 }
4aca6e
 
4aca6e
+static int sctp_show(struct filter *f)
4aca6e
+{
4aca6e
+	if (!filter_af_get(f, AF_INET) && !filter_af_get(f, AF_INET6))
4aca6e
+		return 0;
4aca6e
+
4aca6e
+	if (!getenv("PROC_NET_SCTP") && !getenv("PROC_ROOT")
4aca6e
+	    && inet_show_netlink(f, NULL, IPPROTO_SCTP) == 0)
4aca6e
+		return 0;
4aca6e
+
4aca6e
+	return 0;
4aca6e
+}
4aca6e
 
4aca6e
 static int dgram_show_line(char *line, const struct filter *f, int family)
4aca6e
 {
4aca6e
@@ -3343,6 +3532,7 @@ static void _usage(FILE *dest)
4aca6e
 "   -6, --ipv6          display only IP version 6 sockets\n"
4aca6e
 "   -0, --packet        display PACKET sockets\n"
4aca6e
 "   -t, --tcp           display only TCP sockets\n"
4aca6e
+"   -S, --sctp          display only SCTP sockets\n"
4aca6e
 "   -u, --udp           display only UDP sockets\n"
4aca6e
 "   -d, --dccp          display only DCCP sockets\n"
4aca6e
 "   -w, --raw           display only RAW sockets\n"
4aca6e
@@ -3419,6 +3609,7 @@ static const struct option long_opts[] = {
4aca6e
 	{ "bpf", 0, 0, 'b' },
4aca6e
 	{ "dccp", 0, 0, 'd' },
4aca6e
 	{ "tcp", 0, 0, 't' },
4aca6e
+	{ "sctp", 0, 0, 'S' },
4aca6e
 	{ "udp", 0, 0, 'u' },
4aca6e
 	{ "raw", 0, 0, 'w' },
4aca6e
 	{ "unix", 0, 0, 'x' },
4aca6e
@@ -3452,7 +3643,7 @@ int main(int argc, char *argv[])
4aca6e
 	int ch;
4aca6e
 	int state_filter = 0;
4aca6e
 
4aca6e
-	while ((ch = getopt_long(argc, argv, "dhaletuwxnro460spbf:miA:D:F:vVzZN:",
4aca6e
+	while ((ch = getopt_long(argc, argv, "dhaletuwxnro460spbf:miA:D:F:vVzZN:S",
4aca6e
 				 long_opts, NULL)) != EOF) {
4aca6e
 		switch(ch) {
4aca6e
 		case 'n':
4aca6e
@@ -3488,6 +3679,9 @@ int main(int argc, char *argv[])
4aca6e
 		case 't':
4aca6e
 			filter_db_set(&current_filter, TCP_DB);
4aca6e
 			break;
4aca6e
+		case 'S':
4aca6e
+			filter_db_set(&current_filter, SCTP_DB);
4aca6e
+			break;
4aca6e
 		case 'u':
4aca6e
 			filter_db_set(&current_filter, UDP_DB);
4aca6e
 			break;
4aca6e
@@ -3551,6 +3745,7 @@ int main(int argc, char *argv[])
4aca6e
 					filter_db_set(&current_filter, UDP_DB);
4aca6e
 					filter_db_set(&current_filter, DCCP_DB);
4aca6e
 					filter_db_set(&current_filter, TCP_DB);
4aca6e
+					filter_db_set(&current_filter, SCTP_DB);
4aca6e
 					filter_db_set(&current_filter, RAW_DB);
4aca6e
 				} else if (strcmp(p, "udp") == 0) {
4aca6e
 					filter_db_set(&current_filter, UDP_DB);
4aca6e
@@ -3558,6 +3753,8 @@ int main(int argc, char *argv[])
4aca6e
 					filter_db_set(&current_filter, DCCP_DB);
4aca6e
 				} else if (strcmp(p, "tcp") == 0) {
4aca6e
 					filter_db_set(&current_filter, TCP_DB);
4aca6e
+				} else if (strcmp(p, "sctp") == 0) {
4aca6e
+					filter_db_set(&current_filter, SCTP_DB);
4aca6e
 				} else if (strcmp(p, "raw") == 0) {
4aca6e
 					filter_db_set(&current_filter, RAW_DB);
4aca6e
 				} else if (strcmp(p, "unix") == 0) {
4aca6e
@@ -3682,7 +3879,7 @@ int main(int argc, char *argv[])
4aca6e
 	filter_merge_defaults(&current_filter);
4aca6e
 
4aca6e
 	if (resolve_services && resolve_hosts &&
4aca6e
-	    (current_filter.dbs&(UNIX_DBM|(1<
4aca6e
+	    (current_filter.dbs&(UNIX_DBM|(1<
4aca6e
 		init_service_resolver();
4aca6e
 
4aca6e
 
4aca6e
@@ -3790,6 +3987,8 @@ int main(int argc, char *argv[])
4aca6e
 		tcp_show(&current_filter, IPPROTO_TCP);
4aca6e
 	if (current_filter.dbs & (1<
4aca6e
 		tcp_show(&current_filter, IPPROTO_DCCP);
4aca6e
+	if (current_filter.dbs & (1<
4aca6e
+		sctp_show(&current_filter);
4aca6e
 
4aca6e
 	if (show_users || show_proc_ctx || show_sock_ctx)
4aca6e
 		user_ent_destroy();
4aca6e
-- 
4aca6e
1.8.3.1
4aca6e