Daniel Jakots wrote:
> Hi,
> 
> With nc(1) you can do:
> nc -zv example.com 80
> or
> nc -zv example.com http
> which does the same. This works well unless the service name has a dash:
> $ nc -zv example.com syslog-tls
> nc: service "tls" unknown
> 
> This is because nc(1) is able to do some port scanning and the
> delimiter used for the range is the dash. When it sees a dash, it
> thinks it's a port range.
> 
> nc(1) is not the only software that takes an input that can be a port,
> a range or a service name: pf is in this case too. In pf the delimiter
> used is ":" so this works fine.
> 
> Here's a diff that change the delimiter to ":". This breaks existing
> scripts but it would make the syntax like pf.conf instead of using
> another symbol for a port range.
> 
> If you have a better idea how to solve this problem, please share!

This preserves the low-high syntax, adds low:high syntax, and also tries to be
smarter about service-name.

First look for :. That's a range.
Next look for -. Then check it's not a service name. That's a range.
Otherwise it's a port.

It may work, but needs testing.

Index: netcat.c
===================================================================
RCS file: /cvs/src/usr.bin/nc/netcat.c,v
retrieving revision 1.199
diff -u -p -r1.199 netcat.c
--- netcat.c    29 Nov 2018 14:25:06 -0000      1.199
+++ netcat.c    22 Dec 2018 22:27:47 -0000
@@ -1426,46 +1426,53 @@ build_ports(char *p)
        char *n;
        int hi, lo, cp;
        int x = 0;
+       char *tmp;
 
-       if ((n = strchr(p, '-')) != NULL) {
-               *n = '\0';
-               n++;
-
-               /* Make sure the ports are in order: lowest->highest. */
-               hi = strtoport(n, uflag);
-               lo = strtoport(p, uflag);
-               if (lo > hi) {
-                       cp = hi;
-                       hi = lo;
-                       lo = cp;
-               }
+       if ((n = strchr(p, ':')) != NULL)
+               goto range;
 
-               /*
-                * Initialize portlist with a random permutation.  Based on
-                * Knuth, as in ip_randomid() in sys/netinet/ip_id.c.
-                */
-               if (rflag) {
-                       for (x = 0; x <= hi - lo; x++) {
-                               cp = arc4random_uniform(x + 1);
-                               portlist[x] = portlist[cp];
-                               if (asprintf(&portlist[cp], "%d", x + lo) < 0)
-                                       err(1, "asprintf");
-                       }
-               } else { /* Load ports sequentially. */
-                       for (cp = lo; cp <= hi; cp++) {
-                               if (asprintf(&portlist[x], "%d", cp) < 0)
-                                       err(1, "asprintf");
-                               x++;
-                       }
-               }
-       } else {
-               char *tmp;
+       if ((n = strchr(p, '-')) != NULL)
+               if (getservbyname(p, uflag ? "udp" : "tcp") == NULL)
+                       goto range;
+
+       hi = strtoport(p, uflag);
+       if (asprintf(&tmp, "%d", hi) != -1)
+               portlist[0] = tmp;
+       else
+               err(1, NULL);
+
+       return;
 
-               hi = strtoport(p, uflag);
-               if (asprintf(&tmp, "%d", hi) != -1)
-                       portlist[0] = tmp;
-               else
-                       err(1, NULL);
+range:
+       *n = '\0';
+       n++;
+
+       /* Make sure the ports are in order: lowest->highest. */
+       hi = strtoport(n, uflag);
+       lo = strtoport(p, uflag);
+       if (lo > hi) {
+               cp = hi;
+               hi = lo;
+               lo = cp;
+       }
+
+       /*
+        * Initialize portlist with a random permutation.  Based on
+        * Knuth, as in ip_randomid() in sys/netinet/ip_id.c.
+        */
+       if (rflag) {
+               for (x = 0; x <= hi - lo; x++) {
+                       cp = arc4random_uniform(x + 1);
+                       portlist[x] = portlist[cp];
+                       if (asprintf(&portlist[cp], "%d", x + lo) < 0)
+                               err(1, "asprintf");
+               }
+       } else { /* Load ports sequentially. */
+               for (cp = lo; cp <= hi; cp++) {
+                       if (asprintf(&portlist[x], "%d", cp) < 0)
+                               err(1, "asprintf");
+                       x++;
+               }
        }
 }
 

Reply via email to