Why won't my nc talk to your nc?
In today's lab (15 Oct 2025), I asked
you to try doing an nc-based chat from your computer to your
friend's computer. As several of you noted, that doesn't always work.
This document gives you some background on why.
My experiments with Bridger
Last year, my friend and office-next-door neighbor Bridger Herman and I did a couple experiments. Here's my report.
Experiment 1
- Bridger opens Terminal on his Mac laptop. IP address 10.133.Y.Z.
- Jeff opens Terminal on his Mac laptop. IP address 10.133.W.X
- Server:
nc -l 5555in Bridger's terminal - Client:
nc 10.133.Y.Z 5555in Jeff's terminal - chat works fine
Experiment 2
- Bridger opens Terminal on his Mac laptop. IP address 10.133.Y.Z.
- Jeff opens terminal on his Kali VM on his laptop. IP address 172.16.41.134
- Server:
nc -l 5555in Bridger's terminal - Client:
nc 10.133.Y.Z 5555in Jeff's Kali terminal - chat works fine
Experiment 3
- Bridger opens Terminal on his Mac laptop. IP address 10.133.Y.Z.
- Jeff opens terminal on his Kali VM on his laptop. IP address 172.16.41.134
- Server:
nc -l -p 5555in Jeff's Kali terminal - Client:
nc 10.133.Y.Z 5555in Bridger's terminal - chat connection fails
- Client:
nc 172.16.41.134 5555in Bridger's terminal - chat connection fails
IPv4 addresses for private internets
There are three blocks of IP addresses officially dedicated to "private internets":
- 10.*.*.*
- 172.16.0.0 - 172.31.255.255
- 192.168.*.*
This is discussed in RFC 1918: Address Allocation for Private Internets (see in particular section 3).
The idea is that a local network (e.g., Carleton's on-campus network) can assign addresses from these three blocks to devices within the network, which will be able to communicate with each other using those addresses. For example in Experiment 1 above, Bridger's laptop and my laptop could communicate using their respective 10.*.*.* addresses.
But if I want to use my laptop to communicate with stolaf.edu (199.91.183.19), something weird happens. My initial packet to stolaf.edu (say, a TCP SYN packet to port 443 to start a TCP handshake with a web server) will pass from my laptop (10.133.W.X) through a couple more hops on campus, eventually leaving campus via one of Carleton's gateway routers. By the time my packet arrives at stolaf.edu, my "sender IP" in the IP header of the packet will not say 10.133.W.X; rather, it will say 137.22.90.111 or one of the other IP addresses associated with Carleton's gateways. That is because Carleton's router translates my local-network address into one of its own non-local addresses. When stolaf.edu replies, its "destination IP" will be 137.22.90.111, so Carleton's gateway router will have to translate that back to 10.133.W.X before forwarding the packet to my laptop. (You might want to think about all the outgoing packets from Carleton's network at any given moment, and how the gateway router is going to go about doing these address translations.)
Anyway, the upshot is that nobody outside Carleton's local network can communicate with my laptop by using the address 10.133.W.X, but Bridger's laptop can, because we're both on the local network. Note also that this system prevents devices outside our local network from initiating connections with my laptop, since Carleton's router will say "10.133.W.X? Never heard of it."
What about Virtual Machines?
Every host operating system has the ability to create its own network for use among entities on that host OS. So, for example, my laptop can make a network consisting entirely of the host OS (macOS in this case) and Kali in my VMWare VM. Today, macOS is assigning itself the local-to-this-computer address of 172.16.41.1 and it's assigning Kali the address of 172.16.41.134. Note that both these addresses are from one of the private network address blocks listed above.
Result? Kali and my macOS can talk to each other just fine using their 172.16.41.* addresses.
What if Kali tries to talk to stolaf.edu? The initial SYN packet starts out with source address 172.16.41.134. Then my macOS translates it to 10.133.W.X before forwarding the packet to the Carleton local network. Then Carleton's gateway router translates that to 137.22.90.111 (or one of its other outward-facing IP addresses). And then two address translations happen when stolaf.edu replies--one going from the open internet through to the Carleton local network, and another going from the Carleton local network to my mini-network on my laptop.
So what's going on here?
- Experiment 1. Both Bridger's and my laptops are on Carleton's local network. No address translation is required, and everything works fine.
- Experiment 2. Kali on my laptop initiates the connection, and my macOS translates 172.16.41.134 to 10.133.W.X and saves information about that translation and the attempted TCP connection. Then when Bridger's laptop replies, my macOS is able to translate its destination address back to my mini-local-network address 172.16.41.134. So that works, because Kali initiated.
- Experiment 3. When Bridger attempts to contact 172.16.41.134, there is no such IP address available on Carleton's local network, and because it's a local address, Carleton's gateway router doesn't try to forward the connection out into the world, either. If Bridger tries 10.133.W.X instead, there's no connection, because there's no server listening at port 5555 at that IP address.
This is a very rough intro to various methods of doing address translation and maintaining local networks with address spaces isolated from outside networks. There's tons more info about this. You could pursue it further by searching for "Network Address Translation" if you're interested.