A fair number of devices have accumulated at home: bulbs, a robot vacuum, cameras, a printer, two computers, phones, a plug, a temperature sensor.
A simple question: what is on the network right now? I decided to write myself a panel. I started in the wrong place.
First attempt: TCP
The logic: try to connect to a few common ports on every address from 1 to 254. If something answers, a device is there.
254 addresses × 4 ports = 1,016 connection attempts
each failure ≈ 1 s timeout
Doing it concurrently should speed it up, I thought. On Windows I hit two walls:
- The half-open connection quota. The OS caps how many connections may be pending at once; above that, new ones queue.
- Closing a socket blocks. The close call on a timed-out socket did not return immediately. That was why the scan looked stuck — the work was done and the cleanup was jammed.
Six minutes in, progress was at 18%. I stopped it.
Concurrency cannot be raised without limit: select-based waiting is bounded by FD_SETSIZE and behaviour becomes undefined above it. The fix is not more sockets but a pool that keeps open sockets under the ceiling.
One layer down
Then I noticed the obvious: device discovery is not a transport-layer job.
TCP establishes connections between endpoints. I do not want a connection; I want to know whether something is there. That information already exists one layer down: two devices on the same local network need a MAC address to talk, ARP performs that mapping, and the operating system keeps the result in a table.
# short ping sweep of the subnet — no waiting for replies
for ip in 192.168.1.1..254: ping -n 1 -w 100 $ip
# read the table the OS has already filled
arp -a
192.168.1.1 a4-2b-8c-… dynamic ← router
192.168.1.34 ec-fa-bc-… dynamic ← Espressif (bulb)
192.168.1.51 28-6d-97-… dynamic ← Xiaomi (vacuum)
…
Three seconds. Forty-one devices.
With a bonus: the first three bytes of a MAC address are assigned to a manufacturer and listed publicly. So the make falls out of the address itself, without asking anything.
Where a name comes from
“Espressif” means nothing to a user. For names I try three sources in order: reverse DNS (if the router keeps records), mDNS (if the device advertises itself), NetBIOS (Windows machines).
If all three fail the device stays “unknown” and is shown by manufacturer. I do not invent names — a row saying “probably a camera” is worse than a camera that is not there.
Port scanning comes after
Port scanning was not the wrong tool; it was in the wrong order. First find who exists, then look at the ports of only those. Scanning 41 devices instead of 254 addresses makes it manageable.
The results were instructive. One camera served a stream with no authentication. One device had opened its admin interface without a password. Another was running an HTTPS service whose certificate expired three years ago.
A home network is not a security boundary. It is a cupboard — the door is shut but there is no lock.
What I learned
The first question when solving a problem is not “which tool?” but “which layer?”
Look for the answer one layer too high and the work grows, accuracy falls, and you start colliding with operating system limits. If the answer is already produced one layer down, your job is not to produce it but to read it.
The difference between six minutes and three seconds was not a better algorithm. It was the right layer.