bin/60598: nc(1) UDP port scans are not useful.

"[email protected] via gnats" <[email protected]>
Newsgroups gmane.os.netbsd.bugs
Message-ID <[email protected]>
>Number:         60598
>Category:       bin
>Synopsis:       nc(1) UDP port scans are not useful.
>Confidential:   no
>Severity:       non-critical
>Priority:       low
>Responsible:    bin-bug-people
>State:          open
>Class:          change-request
>Submitter-Id:   net
>Arrival-Date:   Sat Aug 15 09:05:01 +0000 2026
>Originator:     RVP
>Release:        11.99.7
>Organization:
>Environment:
NetBSD CoreBook.local 11.99.7 NetBSD 11.99.7 (COREBOOK_DIAG) #0: Sat Aug 15 04:21:15 UTC 2026  [email protected]:/tmp/obj/usr/src/sys/arch/amd64/compile/COREBOOK_DIAG amd64
>Description:
Doing a UDP port scans using nc(1) right now is kinda pointless:

```
$ nc -uvz 192.168.68.1 50-60
Connection to 192.168.68.1 50 port [udp/re-mail-ck] succeeded!
Connection to 192.168.68.1 51 port [udp/*] succeeded!
Connection to 192.168.68.1 52 port [udp/xns-time] succeeded!
Connection to 192.168.68.1 53 port [udp/domain] succeeded!
Connection to 192.168.68.1 54 port [udp/xns-ch] succeeded!
Connection to 192.168.68.1 55 port [udp/isi-gl] succeeded!
Connection to 192.168.68.1 56 port [udp/xns-auth] succeeded!
Connection to 192.168.68.1 57 port [udp/*] succeeded!
Connection to 192.168.68.1 58 port [udp/xns-mail] succeeded!
Connection to 192.168.68.1 59 port [udp/*] succeeded!
Connection to 192.168.68.1 60 port [udp/*] succeeded!
$
```
All ports show up because nc(1) blasts through all the ports, and
expects the write to immediately return an error if a UDP port is
unreachable.

>How-To-Repeat:
As shown above.
>Fix:
Wait a bit for the ICMP port unreachable message to reach us.
Patch is almost the same as in Debian's `netcat-openbsd' package.

```
diff -urN usr.bin/nc.orig/netcat.c usr.bin/nc/netcat.c
--- usr.bin/nc.orig/netcat.c	2026-03-03 03:54:49.716087313 +0000
+++ usr.bin/nc/netcat.c	2026-06-04 11:37:51.676518886 +0000
@@ -1518,6 +1518,8 @@
 	}
 }
 
+#define UDP_SCAN_TIMEOUT	3	/* seconds */
+
 /*
  * udptest()
  * Do a few writes to see if the UDP port is there.
@@ -1526,15 +1528,23 @@
 int
 udptest(int s)
 {
-	int i, ret;
+	int i, t = (timeout == -1) ? UDP_SCAN_TIMEOUT : (timeout / 1000);
+ 
+ 	/* Only write to the socket in scan mode or interactive mode. */
+ 	if (!zflag && !isatty(STDIN_FILENO))
+ 		return 0;
+ 
+	if ((write(s, "X", 1) != 1) ||
+	    ((write(s, "X", 1) != 1) && (errno == ECONNREFUSED)))
+		return -1;
 
-	for (i = 0; i <= 3; i++) {
-		if (write(s, "X", 1) == 1)
-			ret = 1;
-		else
-			ret = -1;
-	}
-	return (ret);
+	/* Give the remote host some time to reply. */
+	for (i = 0; i < t; i++) {
+		sleep(1);
+		if ((write(s, "X", 1) != 1) && (errno == ECONNREFUSED))
+			return -1;
+ 	}
+	return 1;
 }
 
 void
```
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.