MINOR: cli/show_fd: report local and report ports when known

FD dumps are not always easy to match against netstat dumps, and often
require an lsof as a third dump. Let's emit the socket family, and the
local and remore ports when the FD is an IPv4/IPv6 socket, this will
significantly ease the matching.

(cherry picked from commit ed9892018c327c61342bf95b2d83f44f27bfc7c4)
Signed-off-by: Willy Tarreau <w@1wt.eu>
diff --git a/src/cli.c b/src/cli.c
index 3331c7c..f629b0c 100644
--- a/src/cli.c
+++ b/src/cli.c
@@ -1102,6 +1102,27 @@
 			if (conn->handle.fd != fd) {
 				chunk_appendf(&trash, " fd=%d(BOGUS)", conn->handle.fd);
 				suspicious = 1;
+			} else {
+				struct sockaddr_storage sa;
+				socklen_t salen;
+
+				salen = sizeof(sa);
+				if (getsockname(fd, (struct sockaddr *)&sa, &salen) != -1) {
+					if (sa.ss_family == AF_INET)
+						chunk_appendf(&trash, " fam=ipv4 lport=%d", ntohs(((const struct sockaddr_in *)&sa)->sin_port));
+					else if (sa.ss_family == AF_INET6)
+						chunk_appendf(&trash, " fam=ipv6 lport=%d", ntohs(((const struct sockaddr_in6 *)&sa)->sin6_port));
+					else if (sa.ss_family == AF_UNIX)
+						chunk_appendf(&trash, " fam=unix");
+				}
+
+				salen = sizeof(sa);
+				if (getpeername(fd, (struct sockaddr *)&sa, &salen) != -1) {
+					if (sa.ss_family == AF_INET)
+						chunk_appendf(&trash, " rport=%d", ntohs(((const struct sockaddr_in *)&sa)->sin_port));
+					else if (sa.ss_family == AF_INET6)
+						chunk_appendf(&trash, " rport=%d", ntohs(((const struct sockaddr_in6 *)&sa)->sin6_port));
+				}
 			}
 
 			if (px)
@@ -1130,9 +1151,22 @@
 			}
 		}
 		else if (fdt.iocb == sock_accept_iocb) {
+			struct sockaddr_storage sa;
+			socklen_t salen;
+
 			chunk_appendf(&trash, ") l.st=%s fe=%s",
 			              listener_state_str(li),
 			              li->bind_conf->frontend->id);
+
+			salen = sizeof(sa);
+			if (getsockname(fd, (struct sockaddr *)&sa, &salen) != -1) {
+				if (sa.ss_family == AF_INET)
+					chunk_appendf(&trash, " fam=ipv4 lport=%d", ntohs(((const struct sockaddr_in *)&sa)->sin_port));
+				else if (sa.ss_family == AF_INET6)
+					chunk_appendf(&trash, " fam=ipv6 lport=%d", ntohs(((const struct sockaddr_in6 *)&sa)->sin6_port));
+				else if (sa.ss_family == AF_UNIX)
+					chunk_appendf(&trash, " fam=unix");
+			}
 		}
 		else
 			chunk_appendf(&trash, ")");