From: Pavel Emelyanov Date: Fri, 17 May 2013 15:02:14 +0000 (-0700) Subject: ss: Show inet and unix sockets' shutdown state X-Git-Tag: v3.10.0~30 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=5b816047537bb04620718e798ec09ac9f7a0ad67;p=thirdparty%2Fiproute2.git ss: Show inet and unix sockets' shutdown state When extended info is requested (-e option) one will be able to observe arrows in the output, like this: ESTAB 0 0 127.0.0.1:41705 127.0.0.1:12345 ino:143321 sk:ffff88003a8cea00 --> ESTAB 0 0 127.0.0.1:46925 127.0.0.1:12346 ino:143322 sk:ffff88003a8ce4c0 <-- ESTAB 0 0 127.0.0.1:51678 127.0.0.1:12347 ino:143323 sk:ffff88003a8cdf80 --- ESTAB 0 0 127.0.0.1:46911 127.0.0.1:12348 ino:143324 sk:ffff88003b7f05c0 <-> for SHUT_RD, SHUT_WR, SHUT_RDWR and non-shutdown sockets respectively. The respective nlattrs in *_diag messages has appeared in Linux v3.7 and are already present in ss's headers. Signed-off-by: Pavel Emelyanov --- diff --git a/misc/ss.c b/misc/ss.c index 2730cb21b..9f6354e32 100644 --- a/misc/ss.c +++ b/misc/ss.c @@ -1354,15 +1354,12 @@ static void print_skmeminfo(struct rtattr *tb[], int attrtype) printf(")"); } -static void tcp_show_info(const struct nlmsghdr *nlh, struct inet_diag_msg *r) +static void tcp_show_info(const struct nlmsghdr *nlh, struct inet_diag_msg *r, + struct rtattr *tb[]) { - struct rtattr * tb[INET_DIAG_MAX+1]; char b1[64]; double rtt = 0; - parse_rtattr(tb, INET_DIAG_MAX, (struct rtattr*)(r+1), - nlh->nlmsg_len - NLMSG_LENGTH(sizeof(*r))); - if (tb[INET_DIAG_SKMEMINFO]) { print_skmeminfo(tb, INET_DIAG_SKMEMINFO); } else if (tb[INET_DIAG_MEMINFO]) { @@ -1447,9 +1444,13 @@ static void tcp_show_info(const struct nlmsghdr *nlh, struct inet_diag_msg *r) static int inet_show_sock(struct nlmsghdr *nlh, struct filter *f) { + struct rtattr * tb[INET_DIAG_MAX+1]; struct inet_diag_msg *r = NLMSG_DATA(nlh); struct tcpstat s; + parse_rtattr(tb, INET_DIAG_MAX, (struct rtattr*)(r+1), + nlh->nlmsg_len - NLMSG_LENGTH(sizeof(*r))); + s.state = r->idiag_state; s.local.family = s.remote.family = r->idiag_family; s.lport = ntohs(r->id.idiag_sport); @@ -1498,10 +1499,15 @@ static int inet_show_sock(struct nlmsghdr *nlh, struct filter *f) if (r->id.idiag_cookie[1] != 0) printf("%08x", r->id.idiag_cookie[1]); printf("%08x", r->id.idiag_cookie[0]); + if (tb[INET_DIAG_SHUTDOWN]) { + unsigned char mask; + mask = *(__u8 *)RTA_DATA(tb[INET_DIAG_SHUTDOWN]); + printf(" %c-%c", mask & 1 ? '-' : '<', mask & 2 ? '-' : '>'); + } } if (show_mem || show_tcpinfo) { printf("\n\t"); - tcp_show_info(nlh, r); + tcp_show_info(nlh, r, tb); } printf("\n"); @@ -2207,6 +2213,14 @@ static int unix_show_sock(struct nlmsghdr *nlh, struct filter *f) print_skmeminfo(tb, UNIX_DIAG_MEMINFO); } + if (show_details) { + if (tb[UNIX_DIAG_SHUTDOWN]) { + unsigned char mask; + mask = *(__u8 *)RTA_DATA(tb[UNIX_DIAG_SHUTDOWN]); + printf(" %c-%c", mask & 1 ? '-' : '<', mask & 2 ? '-' : '>'); + } + } + printf("\n"); return 0;