EYThe LogEmre Yakut
← all entries
Protocol · Debugging · deep

Scanning my home network: six minutes on the wrong layer

I wanted to list the devices on my own network. I scanned with TCP — six minutes later it was still at 18%. Then I dropped one layer and it finished in three seconds.

TCP ile tarama254 hedef × 4 porther biri ~1 sn timeoutWindows: yarı-açık soket kotasıfclose bloklanıyor→ 6 dk sonra hâlâ %18ARP ile keşifzaten L2’de cevap varişletim sistemi tablosunu tutuyorping süpürme + arp -aMAC → üretici eşlemesi→ 3 sn, 41 cihazdoğru katmanı seç: cihaz keşfi bir taşıma katmanı işi değilport taraması sonra gelir — ve o zaman bile eşzamanlılık FD_SETSIZE altında kalmalı

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.

a separate lesson picked up along the way

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.

ProtocolDebugging