Author: tuexen
Date: Tue Sep 12 13:34:43 2017
New Revision: 323492
URL: https://svnweb.freebsd.org/changeset/base/323492

Log:
  Add support to print the TCP stack being used.
  
  Sponsored by: Netflix, Inc.

Modified:
  head/sys/netinet/tcp_var.h
  head/usr.bin/sockstat/sockstat.1
  head/usr.bin/sockstat/sockstat.c

Modified: head/sys/netinet/tcp_var.h
==============================================================================
--- head/sys/netinet/tcp_var.h  Tue Sep 12 13:21:14 2017        (r323491)
+++ head/sys/netinet/tcp_var.h  Tue Sep 12 13:34:43 2017        (r323492)
@@ -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) */

Modified: head/usr.bin/sockstat/sockstat.1
==============================================================================
--- head/usr.bin/sockstat/sockstat.1    Tue Sep 12 13:21:14 2017        
(r323491)
+++ head/usr.bin/sockstat/sockstat.1    Tue Sep 12 13:34:43 2017        
(r323492)
@@ -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,

Modified: head/usr.bin/sockstat/sockstat.c
==============================================================================
--- head/usr.bin/sockstat/sockstat.c    Tue Sep 12 13:21:14 2017        
(r323491)
+++ head/usr.bin/sockstat/sockstat.c    Tue Sep 12 13:34:43 2017        
(r323492)
@@ -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,22 +1045,37 @@ 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)
                        laddr = laddr->next;
@@ -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;
@@ -1189,6 +1211,9 @@ main(int argc, char *argv[])
                        break;
                case 'P':
                        protos_defined = parse_protos(optarg);
+                       break;
+               case 'S':
+                       opt_S = 1;
                        break;
                case 's':
                        opt_s = 1;
_______________________________________________
svn-src-head@freebsd.org mailing list
https://lists.freebsd.org/mailman/listinfo/svn-src-head
To unsubscribe, send any mail to "svn-src-head-unsubscr...@freebsd.org"

Reply via email to