[PATCH] Allow tcpdrop to use non-space separators

Andre Oppermann andre at freebsd.org
Tue Jan 29 23:11:44 UTC 2013


On 29.01.2013 18:05, John Baldwin wrote:
> A common use case I have at work is to find a busted connection using netstat
> -n or sockstat and then want to tcpdrop it.  However, tcpdrop requires spaces
> between the address and port so I can't simply cut and paste from one terminal
> window into another to generate the tcpdrop command.  This patch adds support
> for having a decimal (netstat output) or colon (sockstat output) between the
> address and port instead of a space.  It is careful to look for the last of
> these tokens to avoid parsing part of the address as the port.

Excellent.  Can netstat be changed from decimal to colon output as well?
The decimal output is completely outdated and probably from a time when
not even dinosaurs were [created|evolved] yet.  Colon output for port
numbers is *the* standard all around.

-- 
Andre

> Index: tcpdrop.8
> ===================================================================
> --- tcpdrop.8	(revision 246073)
> +++ tcpdrop.8	(working copy)
> @@ -62,6 +62,9 @@
>   .Pp
>   Addresses and ports may be specified by name or numeric value.
>   Both IPv4 and IPv6 address formats are supported.
> +.Pp
> +The addresses and ports may be separated by periods or colons
> +instead of spaces.
>   .Sh EXIT STATUS
>   .Ex -std
>   .Sh EXAMPLES
> Index: tcpdrop.c
> ===================================================================
> --- tcpdrop.c	(revision 246073)
> +++ tcpdrop.c	(working copy)
> @@ -50,6 +50,7 @@
>
>   static bool tcpdrop_list_commands = false;
>
> +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 *);
> @@ -65,6 +66,7 @@
>   int
>   main(int argc, char *argv[])
>   {
> +	char *lport, *fport;
>   	bool dropall;
>   	int ch;
>
> @@ -93,15 +95,43 @@
>   		exit(0);
>   	}
>
> -	if (argc != 4 || tcpdrop_list_commands)
> +	if ((argc != 2 && argc != 4) || tcpdrop_list_commands)
>   		usage();
>
> -	if (!tcpdropbyname(argv[0], argv[1], argv[2], argv[3]))
> +	if (argc == 2) {
> +		lport = findport(argv[0]);
> +		fport = findport(argv[1]);
> +		if (lport == NULL || lport[1] == '\0' || rport == NULL ||
> +		    rport[1] == '\0')
> +			usage();
> +		*lport++ = '\0';
> +		*fport++ = '\0';
> +		if (!tcpdropbyname(argv[0], lport, argv[1], fport))
> +			exit(1);
> +	} else if (!tcpdropbyname(argv[0], argv[1], argv[2], argv[3]))
>   		exit(1);
>
>   	exit(0);
>   }
>
> +static char *
> +findport(const char *arg)
> +{
> +	char *dot, *colon;
> +
> +	/* A strrspn() or strrpbrk() would be nice. */
> +	dot = strrchr(arg, '.');
> +	colon = strrchr(arg, ':');
> +	if (dot == NULL)
> +		return (colon);
> +	if (colon == NULL)
> +		return (dot);
> +	if (dot < colon)
> +		return (colon);
> +	else
> +		return (dot);
> +}
> +
>   static struct xinpgen *
>   getxpcblist(const char *name)
>   {
> @@ -237,7 +267,7 @@
>   	error = getaddrinfo(fhost, fport, &hints, &foreign);
>   	if (error != 0) {
>   		freeaddrinfo(local); /* XXX gratuitous */
> -		errx(1, "getaddrinfo: %s port %s: %s", lhost, lport,
> +		errx(1, "getaddrinfo: %s port %s: %s", fhost, fport,
>   		    gai_strerror(error));
>   	}
>
> @@ -318,6 +348,8 @@
>   {
>   	fprintf(stderr,
>   "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");
>   	exit(1);
>   }
>



More information about the freebsd-net mailing list