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