Author: tuexen
Date: Tue Sep 12 13:39:44 2017
New Revision: 323493
URL: https://svnweb.freebsd.org/changeset/base/323493

Log:
  Allow TCP connections to be filtered by stack and state.
  
  Choose the command line options to be consistent with the ones of
  sockstat.
  
  Sponsored by: Netflix, Inc.

Modified:
  head/usr.sbin/tcpdrop/tcpdrop.8
  head/usr.sbin/tcpdrop/tcpdrop.c

Modified: head/usr.sbin/tcpdrop/tcpdrop.8
==============================================================================
--- head/usr.sbin/tcpdrop/tcpdrop.8     Tue Sep 12 13:34:43 2017        
(r323492)
+++ head/usr.sbin/tcpdrop/tcpdrop.8     Tue Sep 12 13:39:44 2017        
(r323493)
@@ -17,7 +17,7 @@
 .\"
 .\" $FreeBSD$
 .\"
-.Dd January 30, 2013
+.Dd September 12, 2017
 .Dt TCPDROP 8
 .Os
 .Sh NAME
@@ -32,6 +32,16 @@
 .Nm tcpdrop
 .Op Fl l
 .Fl a
+.Nm tcpdrop
+.Op Fl l
+.Fl S Ar stack
+.Nm tcpdrop
+.Op Fl l
+.Fl s Ar state
+.Nm tcpdrop
+.Op Fl l
+.Fl S Ar stack
+.Fl s Ar state
 .Sh DESCRIPTION
 The
 .Nm
@@ -41,15 +51,49 @@ If
 .Fl a
 is specified then
 .Nm
-will attempt to drop all active connections.
+will attempt to drop all TCP connections.
+.Pp
+If
+.Fl S Ar stack
+is specified then
+.Nm
+will attempt to drop all connections using the TCP stack
+.Ar stack .
+.Pp
+If
+.Fl s Ar state
+is specified then
+.Nm
+will attempt to drop all TCP connections being in the state
+.Ar state .
+.Ar state
+is one of
+.Dv SYN_SENT ,
+.Dv SYN_RCVD ,
+.Dv ESTABLISHED ,
+.Dv CLOSE_WAIT ,
+.Dv FIN_WAIT_1 ,
+.Dv CLOSING ,
+.Dv LAST_ACK ,
+.Dv FIN_WAIT_2 , or
+.Dv TIME_WAIT .
+.Pp
 The
 .Fl l
-flag may be given to list the tcpdrop invocation to drop all active
+flag may be given in addition to the
+.Fl a ,
+.Fl S ,
+or
+.Fl s
+options to list the tcpdrop invocation to drop all corresponding TCP
 connections one at a time.
 .Pp
-If
-.Fl a
-is not specified then only the connection between the given local
+If none of the
+.Fl a ,
+.Fl S ,
+or
+.Fl s
+options are specified then only the connection between the given local
 address
 .Ar local-address ,
 port
@@ -88,6 +132,23 @@ port 22, the port used by
 .Xr sshd 8 :
 .Bd -literal -offset indent
 # tcpdrop -l -a | grep -vw 22 | sh
+.Ed
+.Pp
+The following command will drop all connections using the TCP stack
+fastack:
+.Bd -literal -offset indent
+# tcpdrop -S fastack
+.Ed
+.Pp
+To drop all TCP connections in the LAST_ACK state use:
+.Bd -literal -offset indent
+# tcpdrop -s LAST_ACK
+.Ed
+.Pp
+To drop all TCP connections using the TCP stack fastack and being in the
+LAST_ACK state use:
+.Bd -literal -offset indent
+# tcpdrop -S fastack -s LAST_ACK
 .Ed
 .Sh SEE ALSO
 .Xr netstat 1 ,

Modified: head/usr.sbin/tcpdrop/tcpdrop.c
==============================================================================
--- head/usr.sbin/tcpdrop/tcpdrop.c     Tue Sep 12 13:34:43 2017        
(r323492)
+++ head/usr.sbin/tcpdrop/tcpdrop.c     Tue Sep 12 13:39:44 2017        
(r323493)
@@ -54,7 +54,7 @@ static char *findport(const char *);
 static struct xinpgen *getxpcblist(const char *);
 static void sockinfo(const struct sockaddr *, struct host_service *);
 static bool tcpdrop(const struct sockaddr *, const struct sockaddr *);
-static bool tcpdropall(void);
+static bool tcpdropall(const char *, int);
 static bool tcpdropbyname(const char *, const char *, const char *,
     const char *);
 static bool tcpdropconn(const struct in_conninfo *);
@@ -66,13 +66,17 @@ static void usage(void);
 int
 main(int argc, char *argv[])
 {
+       char stack[TCP_FUNCTION_NAME_LEN_MAX];
        char *lport, *fport;
-       bool dropall;
-       int ch;
+       bool dropall, dropallstack;
+       int ch, state;
 
        dropall = false;
+       dropallstack = false;
+       memset(stack, 0, TCP_FUNCTION_NAME_LEN_MAX);
+       state = -1;
 
-       while ((ch = getopt(argc, argv, "al")) != -1) {
+       while ((ch = getopt(argc, argv, "alS:s:")) != -1) {
                switch (ch) {
                case 'a':
                        dropall = true;
@@ -80,6 +84,17 @@ main(int argc, char *argv[])
                case 'l':
                        tcpdrop_list_commands = true;
                        break;
+               case 'S':
+                       dropallstack = true;
+                       strncpy(stack, optarg, TCP_FUNCTION_NAME_LEN_MAX);
+                       break;
+               case 's':
+                       dropallstack = true;
+                       for (state = 0; state < TCP_NSTATES; state++) {
+                               if (strcmp(tcpstates[state], optarg) == 0)
+                                       break;
+                       }
+                       break;
                default:
                        usage();
                }
@@ -87,10 +102,16 @@ main(int argc, char *argv[])
        argc -= optind;
        argv += optind;
 
-       if (dropall) {
+       if (state == TCP_NSTATES ||
+           state == TCPS_CLOSED ||
+           state == TCPS_LISTEN)
+               usage();
+       if (dropall && dropallstack)
+               usage();
+       if (dropall || dropallstack) {
                if (argc != 0)
                        usage();
-               if (!tcpdropall())
+               if (!tcpdropall(stack, state))
                        exit(1);
                exit(0);
        }
@@ -202,7 +223,7 @@ tcpdrop(const struct sockaddr *lsa, const struct socka
 }
 
 static bool
-tcpdropall(void)
+tcpdropall(const char *stack, int state)
 {
        struct xinpgen *head, *xinp;
        struct xtcpcb *xtp;
@@ -234,6 +255,15 @@ tcpdropall(void)
                if (xtp->t_state == TCPS_LISTEN)
                        continue;
 
+               /* If requested, skip sockets not having the requested state. */
+               if ((state != -1) && (xtp->t_state != state))
+                       continue;
+
+               /* If requested, skip sockets not having the requested stack. */
+               if (strnlen(stack, TCP_FUNCTION_NAME_LEN_MAX) > 0 &&
+                   strncmp(xtp->xt_stack, stack, TCP_FUNCTION_NAME_LEN_MAX))
+                       continue;
+
                if (!tcpdropconn(&xip->inp_inc))
                        ok = false;
        }
@@ -348,6 +378,9 @@ usage(void)
 "usage: tcpdrop local-address local-port foreign-address foreign-port\n"
 "       tcpdrop local-address:local-port foreign-address:foreign-port\n"
 "       tcpdrop local-address.local-port foreign-address.foreign-port\n"
-"       tcpdrop [-l] -a\n");
+"       tcpdrop [-l] -a\n"
+"       tcpdrop [-l] -S stack\n"
+"       tcpdrop [-l] -s state\n"
+"       tcpdrop [-l] -S stack -s state\n");
        exit(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