Add support to print the TCP stack being used.

Sponsored by:	Netflix, Inc.
This commit is contained in:
Michael Tuexen 2017-09-12 13:34:43 +00:00
parent 1a2ddb2997
commit e5cccc35c3
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=323492
3 changed files with 57 additions and 21 deletions

View File

@ -655,7 +655,7 @@ struct tcp_hhook_data {
struct xtcpcb {
size_t xt_len; /* length of this structure */
struct xinpcb xt_inp;
char xt_stack[TCP_FUNCTION_NAME_LEN_MAX]; /* (n) */
char xt_stack[TCP_FUNCTION_NAME_LEN_MAX]; /* (s) */
int64_t spare64[8];
int32_t t_state; /* (s,p) */
uint32_t t_flags; /* (s,p) */

View File

@ -27,7 +27,7 @@
.\"
.\" $FreeBSD$
.\"
.Dd August 27, 2015
.Dd September 12, 2017
.Dt SOCKSTAT 1
.Os
.Sh NAME
@ -35,7 +35,7 @@
.Nd list open sockets
.Sh SYNOPSIS
.Nm
.Op Fl 46cLlsu
.Op Fl 46cLlSsu
.Op Fl j Ar jid
.Op Fl p Ar ports
.Op Fl P Ar protocols
@ -83,6 +83,9 @@ The
argument is a comma-separated list of protocol names,
as they are defined in
.Xr protocols 5 .
.It Fl S
Display the protocol stack, if applicable.
This is currently only implemented for TCP.
.It Fl s
Display the protocol state, if applicable.
This is currently only implemented for SCTP and TCP.
@ -143,6 +146,14 @@ if the endpoint could not be determined.
(Internet sockets only)
The address the foreign end of the socket is bound to (see
.Xr getpeername 2 ) .
.It Li STATE
The protocol state if
.Fl s
is specified (only for SCTP or TCP).
.It Li STACK
The protocol stack if
.Fl S
is specified (only for TCP).
.El
.Pp
If a socket is associated with more than one file descriptor,

View File

@ -73,6 +73,7 @@ static int opt_c; /* Show connected sockets */
static int opt_j; /* Show specified jail */
static int opt_L; /* Don't show IPv4 or IPv6 loopback sockets */
static int opt_l; /* Show listening sockets */
static int opt_S; /* Show protocol stack if applicable */
static int opt_s; /* Show protocol state if applicable */
static int opt_u; /* Show Unix domain sockets */
static int opt_v; /* Verbose mode */
@ -106,6 +107,7 @@ struct sock {
int proto;
int state;
const char *protoname;
char stack[TCP_FUNCTION_NAME_LEN_MAX];
struct addr *laddr;
struct addr *faddr;
struct sock *next;
@ -698,8 +700,11 @@ gather_inet(int proto)
sock->laddr = laddr;
sock->faddr = faddr;
sock->vflag = xip->inp_vflag;
if (proto == IPPROTO_TCP)
if (proto == IPPROTO_TCP) {
sock->state = xtp->t_state;
memcpy(sock->stack, xtp->xt_stack,
TCP_FUNCTION_NAME_LEN_MAX);
}
sock->protoname = protoname;
hash = (int)((uintptr_t)sock->socket % HASHSIZE);
sock->next = sockhash[hash];
@ -1040,21 +1045,36 @@ displaysock(struct sock *s, int pos)
default:
abort();
}
if (first && opt_s &&
(s->proto == IPPROTO_SCTP || s->proto == IPPROTO_TCP)) {
while (pos < 80)
pos += xprintf(" ");
switch (s->proto) {
case IPPROTO_SCTP:
pos += xprintf("%s", sctp_state(s->state));
break;
case IPPROTO_TCP:
if (s->state >= 0 && s->state < TCP_NSTATES)
pos +=
xprintf("%s", tcpstates[s->state]);
else
pos += xprintf("?");
break;
if (first) {
if (opt_s &&
(s->proto == IPPROTO_SCTP ||
s->proto == IPPROTO_TCP)) {
while (pos < 80)
pos += xprintf(" ");
switch (s->proto) {
case IPPROTO_SCTP:
pos += xprintf("%s",
sctp_state(s->state));
break;
case IPPROTO_TCP:
if (s->state >= 0 &&
s->state < TCP_NSTATES)
pos +=
xprintf("%s",
tcpstates[s->state]);
else
pos += xprintf("?");
break;
}
}
if (opt_S && s->proto == IPPROTO_TCP) {
while (pos < 80)
pos += xprintf(" ");
if (opt_s)
while (pos < 93)
pos += xprintf(" ");
xprintf("%.*s", TCP_FUNCTION_NAME_LEN_MAX,
s->stack);
}
}
if (laddr != NULL)
@ -1083,6 +1103,8 @@ display(void)
"LOCAL ADDRESS", "FOREIGN ADDRESS");
if (opt_s)
printf(" %-12s", "STATE");
if (opt_S)
printf(" %.*s", TCP_FUNCTION_NAME_LEN_MAX, "STACK");
printf("\n");
setpassent(1);
for (xf = xfiles, n = 0; n < nxfiles; ++n, ++xf) {
@ -1153,7 +1175,7 @@ static void
usage(void)
{
fprintf(stderr,
"usage: sockstat [-46cLlsu] [-j jid] [-p ports] [-P protocols]\n");
"usage: sockstat [-46cLlSsu] [-j jid] [-p ports] [-P protocols]\n");
exit(1);
}
@ -1164,7 +1186,7 @@ main(int argc, char *argv[])
int o, i;
opt_j = -1;
while ((o = getopt(argc, argv, "46cj:Llp:P:suv")) != -1)
while ((o = getopt(argc, argv, "46cj:Llp:P:Ssuv")) != -1)
switch (o) {
case '4':
opt_4 = 1;
@ -1190,6 +1212,9 @@ main(int argc, char *argv[])
case 'P':
protos_defined = parse_protos(optarg);
break;
case 'S':
opt_S = 1;
break;
case 's':
opt_s = 1;
break;