Testing if a port can be reached, using built-in tools other than ol' telnet
carehart.org
carehart.org
The year was 2002, the 2.4 Linux kernel had just been released and I was making money on the side building monitoring software for a few thousand (mostly Solaris) hosts owned by a large German car manufacturer. Everything was built in parallel ksh code, “deployed” to Solaris 8 on Sun E10Ks, and mostly kicked off by cron. Keeping total script runtime down to avoid process buildup and delay was critical. The biggest offender: long timeouts for host/port combinations that would sporadically not be available.
Eventually, I grabbed W. Richard Stevens’ UNIX network programming book and created tcping [0]. FreeBSD, NetBSD, a series of Linux distros picked it up at the time and it was steady decline from there… good times!
[0]: https://github.com/mkirchner/tcping
edit: grammar
(After that it's Russinovich's sysinternala suite.)
Netcat even has port scanning capabilities.
Also worth mentioning that bash also has network capabilities, you can check port like this:
: < /dev/tcp/google.com/80 && echo OK || echo ERRORcan you elaborate? From a stealth perspective, probing for a port will always reveal to the other side that they are being probed
Examples:
- Syslog-ng server will interpret it as valid log messages
- HP JetDirect on port 9100 will print HTTP request: https://twitter.com/AviKivity/status/1405147699557638145
- What if service is protected by fail2ban and accounting protocol errors?
After all, sending anything was not my intention, so I won't send.
This even works on my Mac.
But one issue I encountered was timeout. I just tried:
: < /dev/tcp/google.com/8080 && echo OK || echo ERROR
and it hung. So I asked ChatGPT and it suggested timeout 5 bash -c ': < /dev/tcp/google.com/8080' && echo OK || echo ERRORYeah, I didn't know that. I definitely had a suspicion it was how you say, and "basically" was my fudge word, because I didn't know. I hadn't thought much about it, but I did not know for sure. Thanks for tellin me.
I've thought about this idea: mapping the internet to the Unix filesystem, a la proc. I know TabFS, but I think the mapping could be better.
I think it's an interesting problem to consider what a good mapping would be. But it's all tradeoffs I guess. I haven't thought that much about it. But it did seem interesting.
Maybe not interesting enough to really commit to, because it seemed kinda like a big project. But definitely interesting to consider. What do you think? What kind of mapping would you do?
As it happens (if memory serves) telnet can send some bytes on connection also, in attempting to negotiate terminal settings with the remote “telnet server”. That said the /dev/tcp trick is indeed great for bash though!
# Check if the port is available
is_port_free() {
if [[ "$1" =~ ^[0-9]+$ ]] && [ "$1" -ge 1024 ] && [ "$1" -le 65535 ]; then
echo "Valid port number." >&2
else
echo "Invalid port number." >&2
return 1
fi
if netstat -lnt | awk '$6 == "LISTEN" && $4 ~ ":'$1'$" {exit 1}'; then
# Return a truthy value if the port is available
return 0
else
# Return a falsey value if the port is in use
return 1
fi
}Not when it says "Escape Character is 'CTRL+]'" every time you run it.
Or does that depend on how you run it with the windows version?
python3 -c "import socket, sys; host, port = sys.argv[1], 80; s = socket.socket(socket.AF_INET, socket.SOCK_STREAM); s.settimeout(10); result = s.connect((host, port)); s.close(); exit(result == 0)" unknownlxlaxkck.com 2>/dev/null && echo connected || echo fail
nc -vz host port
is my go-to.It's ancient, but still present on every Linux and MacOS system.
The big downside of this is that you can get clashes. For example, VNC uses 5901 and up on my system. What if I have some other service that uses ports in the same range?
A more sane approach would be to call those ports e.g. vnc/work, vnc/meeting, etc. so there would be no conflicts and you would know what each port is used for. And it would work even if you don't have write-access to /etc/services.
Would both the source and destination ports both be strings? Normally, for a client->server packet, the source port is meaningless, so what string would you use? Or would your new protocol support both string ports and integer ports?
Having ports be strings in the TCP header would make the header considerably longer - supposing your protocol had one fixed length 32 ASCII char string port, you'd be looking at something in the region of a 2x increase in header length.
It'd still be a massive undertaking though.
Much less painful though because only the endpoints would need to know.
More sane, but absolutely slow. Every gateway, NAT, firewall, router and switch between two devices would need 15x more RAM, and even with that RAM would need to parse strings, deal with unicode, etc. All of those are slow operations.
Using 16-bit numbers makes identification and routing of packets very quick.
Actually, we do refer to files by their inode number, not by their name. The system uses the name to lookup the inode number, and then use the inode number.
Maybe I misunderstood you initially[1], but you weren't proposing to keep the numbers and use a lookup service for the name. AIUI, you proposed to replace the number with a name, no?
In which case, absolutely no one is proposing to replace inode numbers with names, so inode numbers/filenames as an example does not validate or lend support to your proposal for replacing port numbers with names.
[1] I'm on a personal quest to stop misunderstanding people in a way that reduces the strength of their argument. It's not going as well as I though it would, and I still do it sometimes.
However it only works on your machine.
If you want to have it work on your local machine, DNS SRV records on your local network would work.
The proposal to use names and not numbers breaks down when you want the rest of the world to follow suit, because it's not technically possible within IP, only on top of IP.
This is exactly my point.
> This is exactly my point.
In which case, refer to my original response to your proposal - it's not practical to slow down every networking device in the world by a large factor.
It's like asking "why aren't we commuting at 1/3 the speed of light?": it's neither feasible nor practical.
Sure, it's possible, in that the physics involved make it possible, but not practical, because the limiting factor is not the physics involved.
For ephemeral ports, it isn't clear what value there would be for a string identifier vs. the fixed-width integer.
You can check a port like this, saves a few round trips on a good day.
$ dstp google.com --port 80
Ping: 27.44ms
DNS: resolving 216.58.212.14
SystemDNS: resolving 2a00:1450:4017:804::200e, 142.250.187.174
TLS: certificate is valid for 64 more days
HTTPS: got 200 OK
[0]: https://github.com/ycd/dstp#motivation $ nc -vzw1 host portI like it much better than MacBook with its incompatible ARM cpu, and outdated commands from some ancient BSD!
My laptop has 64GB RAM and 2TB ssd. And unlike Mac, it drives 4x4k displays via USB4 hub. Even with all those extras, it costs less than Macbook, and I have some hardware budget still available:)
And it came with unlocked bios, no spy software... Windows are basically unsupported by our IT...
No spy software will be installed, and the latest version of macOS is making it harder and harder for people to create malware that can easily infect Macs.
It has little RAM, small disk... so you depend on cloud for build. No Nvidia GPU for CUDA... Some USB externals do not work...
So, you can't legitimately say that the memory is always low and the disk is always small. That's just a configuration thing. If you don't configure it right, then I don't hold out much sympathy for you.
You can also run Linux on a VM if you want. With the native macOS virtualisation stack in UTM it takes about 2 seconds to have a full Linux VM up and running.