If you are going to introduce such complicated semantics, please include a proposal for the manual page change so that we can see if this can be simply described. Being dimply described in the manual page is a marker for whether a change is suitable.
Ted Unangst <[email protected]> wrote: > 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++; > + } > } > } > >
