v0.3.4
Port scans now name the software and version a service reports, can check common UDP services, and report closed ports as closed on Windows instead of filtered. The CLI writes CSV and Markdown tables, inspect gives an OS hint, and the desktop app can update itself. Discovery no longer lists the network broadcast address as a device.
Added
- The CLI can write CSV and Markdown tables.
--csvand--mdwork on every command that returns a list:discover,scan,sweep,dns,ping,arp,interfaces,mdnsandpcap. The columns are the same field names--jsonuses, one row per host, port, record or packet, so a result opens straight in a spreadsheet or pastes into an issue without going throughjq. Text a scanned host chose is made safe for each: a banner that starts like a spreadsheet formula is defused, the same way the desktop app's CSV export already does it, and one containing Markdown or HTML is escaped.
- Port scans show the software and version where a service states them. An SSH server's identification line, a web server's
Serverheader, an FTP or mail server's greeting and a MySQL or MariaDB server's connection greeting usually name the software, often with its version:OpenSSH 9.6p1,nginx 1.25.3,MariaDB 10.11.6. Redis, Valkey and Memcached say nothing until asked, so each gets the one read-only question that returns its version. Scans report this asproductandversionin the JSON, and in a Version column in the CLI, the terminal UI and the desktop app. It's far narrower than nmap's-sV: a service that doesn't announce itself, and isn't one of those three, gets no version.
- UDP scanning.
netscli scan <host> --udpchecks the UDP services most networks run: DNS, NTP, NetBIOS, SSDP and mDNS, each sent the request it expects, or the ports you give with-p. A reply reads as open, with what came back (NTP v4, stratum 2, a UPnP device's server string, a Windows machine's NetBIOS name); a port-unreachable reads as closed; and silence reads asopen|filtered, because UDP can't tell a quiet service from a firewall. It needs no administrator rights. The terminal UI takes/scan <host> --udp, the MCP server'sscan_portstakesudp: true, and the desktop app's Port Scan has a TCP/UDP switch.
- Inspect gives an OS hint.
netscli inspectnow says what the host probably runs, with the clues behind it: a Windows machine's exact version and build from the start of an SMB connection (no login), the distribution an SSH banner names, an(Ubuntu)or IIS web server header, Windows' RPC and file-sharing ports, an Apple or Raspberry Pi network card, and the ping reply's TTL. It also shows the host's MAC address and vendor when it's on the same network. It's a hint, not nmap's packet fingerprinting, and needs no administrator rights. The same hint is in the terminal UI, the desktop app's Inspect details and the MCP server'sinspect_host.
- The desktop app can update itself. It already told you when a newer release was out and linked to the release page. Now, where it can, the notice opens a dialog with the release notes and an Install and restart button. The update is downloaded, checked against NetsCLI's signing key, installed, and the app reopens. Nothing downloads unless you click it, and the existing setting still turns the check off entirely.
This takes effect from the version after this one. An app can only update itself if it was built with the updater, so 0.3.4 is the first that can, and 0.3.5 is the first update it will install.
Changed
- Discovery reads the Windows device table directly instead of running
arp -aand parsing its text. On an idle machine that makes no measurable difference (arp -atook 65 ms), but it removes a program start from every discover and sweep, and under heavy CPU loadarp -atook about 4 seconds on the same machine.
Fixed
- Discovery reported the broadcast address as a device. The network's device table on Windows lists
x.x.x.255with the MACff:ff:ff:ff:ff:ff, and discovery listed it as a host that ignored ping (and a sweep then scanned it). The network and broadcast addresses, and broadcast and multicast MACs, are no longer reported. - Closed ports showed as filtered on Windows. Windows waits about two seconds before reporting a refused connection, and the scan stops waiting after half a second, so a port that was plainly closed came back as filtered. The scan now reports it as closed straight away. A scan of 1,024 ports on a LAN machine went from 1,022 filtered to 1,022 closed.
- The macOS app could be refused as broken on Apple Silicon. Its only signature was the one Apple's linker puts on every arm64 program, which claims the app's files are sealed when nothing sealed them. macOS's own checks fail it with "code has no resources but signature indicates they must be present", a broken app rather than one from an unidentified developer, so the Open Anyway route the site describes may never be offered. The whole app is now ad-hoc signed, which seals it, and the release checks the app inside the finished
.dmgbefore shipping it. It is still not notarized, so the first launch still goes through Open Anyway in System Settings → Privacy & Security. - Redis, DNS, NFS, SOCKS and Prometheus ports were probed as if they spoke TLS. The scanner treated any service name ending in "s" as a TLS variant, a rule meant for
imapsandpop3s, so these ports got a TLS handshake instead of having their greeting read. The TLS services are now listed by name. - Installing the desktop app with Scoop now adds it to the Start menu. The manifest's shortcut pointed at
NetsCLI.exe, a file that is in no version of the package: Scoop extracts the MSI rather than running it, which leaves the app atPFiles\NetsCLI\netscli-gui.exe. Scoop reported "Creating shortcut ... failed" and finished the install anyway, so the app was installed with no way to launch it but finding the folder. The manifest now flattens that folder and names the real executable, and the publish job sets both on every release. - The desktop app itself is signed, not only its installer. Since 0.3.3 the
.msihas carried an Authenticode signature, butnetscli-gui.exeinside it did not, and that is the file SmartScreen and antivirus look at when the app runs. It is now signed during the build, before it is packed into the installer, and the release checks the finished MSI's contents before shipping it. Measured on the published 0.3.3 installer: the MSI's signature is valid, the app inside it is unsigned.