svn commit: r323493 - head/usr.sbin/tcpdrop

Michael Tuexen tuexen at FreeBSD.org
Tue Sep 12 13:39:45 UTC 2017


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);
 }


More information about the svn-src-all mailing list