From 0b25d373a75742682f17e2f421c6b856c8e24e5a Mon Sep 17 00:00:00 2001 From: jhb Date: Wed, 30 Jan 2013 18:24:29 +0000 Subject: Allow the address and ports to be separated by a colon or period rather than a space to permit directly pasting the output of commands such as netstat and sockstat on the command line. Reviewed by: net MFC after: 1 week --- usr.sbin/tcpdrop/tcpdrop.8 | 5 ++++- usr.sbin/tcpdrop/tcpdrop.c | 38 +++++++++++++++++++++++++++++++++++--- 2 files changed, 39 insertions(+), 4 deletions(-) (limited to 'usr.sbin/tcpdrop') diff --git a/usr.sbin/tcpdrop/tcpdrop.8 b/usr.sbin/tcpdrop/tcpdrop.8 index 93bfe8e..9649dec 100644 --- a/usr.sbin/tcpdrop/tcpdrop.8 +++ b/usr.sbin/tcpdrop/tcpdrop.8 @@ -17,7 +17,7 @@ .\" .\" $FreeBSD$ .\" -.Dd March 24, 2009 +.Dd January 30, 2013 .Dt TCPDROP 8 .Os .Sh NAME @@ -62,6 +62,9 @@ will be dropped. .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 diff --git a/usr.sbin/tcpdrop/tcpdrop.c b/usr.sbin/tcpdrop/tcpdrop.c index dce6c6d..ef3f6bd 100644 --- a/usr.sbin/tcpdrop/tcpdrop.c +++ b/usr.sbin/tcpdrop/tcpdrop.c @@ -50,6 +50,7 @@ struct host_service { 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 @@ static void usage(void); int main(int argc, char *argv[]) { + char *lport, *fport; bool dropall; int ch; @@ -93,15 +95,43 @@ main(int argc, char *argv[]) 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' || fport == NULL || + fport[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 @@ tcpdropbyname(const char *lhost, const char *lport, const char *fhost, 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 @@ usage(void) { 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); } -- cgit v1.1