There's a special kind of homelab itch that comes from an IP address you can't explain. I had three: 192.168.4.22, 192.168.4.44, and 192.168.4.81. No hostnames, no PTR records, and nothing in Home Assistant claimed them. One of those had been bugging me for months, and I had a sneaking suspicion it was a TV.

Normally, I'd ask my DNS server, but that plan went sideways fast. So I turned my Home Assistant VM into a network probe and made the devices introduce themselves. You can do the same thing with nothing but curl, and there's no need to install something like NetAlertX or ntopng first.

The one tool that could answer this in a single query was down

Because I was making it more reliable

My first stop for "what is this IP?" is always Technitium. Its query logs tell you exactly what a client has been looking up, and a smart TV phoning home to its manufacturer gives itself away in seconds. Except every call I made through the Technitium MCP server came back with the same thing: {"error":"fetch failed"}

DNS itself was fine. Lookups against 192.168.4.59 resolved normally, so the MCP endpoint was the casualty, not the resolver. The reason was entirely my fault. I was in the middle of rebuilding Technitium for high availability at the time, so the DNS server that would have solved this in one query was offline because I was making it more reliable. So I needed another way to see my own network, from a session that couldn't see it at all.

Borrow a machine that already lives on your LAN

Home Assistant's VM makes a surprisingly good probe

home assistant devices page

I run Home Assistant OS as a VM on Proxmox, and the QEMU guest agent is enabled. That agent exists so Proxmox can report the VM's IP and shut it down cleanly, but it also lets the host run commands inside the guest. Anything that can talk to the Proxmox API can borrow the VM's network position. My chain ran from a cloud session to the Proxmox API, to the guest agent, to a shell on the LAN. From the Proxmox host shell, the equivalent is a one-liner: qm guest exec [guest number] -- ping -c 2 ip.address.goes.here

You don't need Proxmox for any of this. Any Linux box on the same subnet with curl will do the job, including a Raspberry Pi or a spare LXC. The guest agent is just the version for when nothing else will talk to you. There's one catch. The HAOS shell is BusyBox, and rather spartan. There's no python3, and `nc` wouldn't report success even on a port I knew was open. I burned two rounds on netcat before giving up.

Mystery devices play dead, so poke them first

Wi-Fi power-save lies to ping

pinging from haos container

My first pass was simple: ping all three, read the neighbor table, and try a reverse lookup on each. Only one answered, and every PTR record came back empty:

192.168.4.22 dev enp6s18 lladdr 2c:1b:3a:b8:38:fd REACHABLE
** server can't find 44.4.168.192.in-addr.arpa: NXDOMAIN

It looked like .44 and .81 were offline. They weren't. Wi-Fi clients in power save mode sleep through an ICMP ping, but a TCP connection attempt tends to wake them. So I paired a curl request with the ping, then read the neighbor table immediately:

curl -s -m 2 http://192.168.4.44/ ; ip neigh show 192.168.4.44

And suddenly both devices were very much alive:

192.168.4.44 dev enp6s18 lladdr 00:1c:c2:9c:fd:b2 REACHABLE
192.168.4.81 dev enp6s18 lladdr 20:f1:b2:51:27:b4 REACHABLE

Waking them up with TCP stimulus then ip neigh turned out to be a reliable pattern. Now I had MAC addresses for all three, which is where the real unmasking starts.

Curl exit codes make a decent port scanner

When you don't have nmap, improvise

use proxmox to find network devices

Without nmap, netcat, or Python, curl's exit codes told me which ports were open and which were closed. Code 7 means refused, 28 means timed out, and anything else means something answered. Quick-and-dirty, but it works:

for p in 7000 8008 8009 8443 5555 6668; do curl -s -m 2 -o /dev/null http://192.168.4.22:$p/; echo "$p rc=$?"; done

On .22, ports 8009 and 8443 returned code 52 (an empty reply, so something is listening), and 7000 returned 0. Port 8009 is Google Cast, 7000 is AirPlay. In my house, anything running both is a TV.

Let the device tell you its own name

Cast and AirPlay are surprisingly chatty

using cast to identify device

Google Cast devices expose an unauthenticated info endpoint on port 8008, and it just tells you what the device is: curl http://192.168.4.22:8008/setup/eureka_info

The response included "name":"Office TV", a Cast build of 3.72.446070, and an SSDP UDN of 329f5c1c-907b-2cff-d3e1-f3a9ebb94f94. AirPlay's info endpoint on port 7000 returns a binary plist, which is ugly but still readable if you pull the strings out:

curl -s http://192.168.4.22:7000/info | strings

That plist contained "TCL", "Android", "Smart TV Pro", and a firmware build date of March 11, 2026. Then I went back to Home Assistant, where the device registry listed `media_player.office_tv` as a TCL Smart TV Pro, with a Cast ID that matched that SSDP UDN exactly. Three independent sources, one answer. The TV that had annoyed me for months was my own Google TV in the office. I did it to myself (mostly).

Then I double-checked on the TV's settings pages. The MAC address matched, although the IP address had changed because DHCP had assigned a new one. IP addresses make lousy identifiers at best; it's best to keep track of the MAC address anyway.

The MAC address fills in the rest

The other two devices had no open ports at all. I swept about 35 ports on each, including 5555 (ADB) and 6668 (Tuya's local protocol), and every one was refused or filtered. Neither showed up in Home Assistant either: a template loop over all 14 devices in my registry found zero hits. These were client-only devices, so the MAC address was all I had left.

The first three bytes of a MAC address (the OUI) identify the manufacturer. My first instinct was an offline lookup with Python's netaddr package, and it flat-out failed: NotRegisteredError: OUI 2890554 not registered!

That's TCL's Wi-Fi module prefix, registered in April 2025, and the bundled IEEE database simply didn't know it existed yet. Vendors register new blocks constantly now, so use a live lookup like maclookup.app instead. That gave me:

IP

MAC prefix

Vendor

Open ports

Verdict

192.168.4.22 (now .121)

2c:1b:3a

Hui Zhou Gaoshengda (ODM Wi-Fi module)

8008, 8009, 8443, 7000

TCL Smart TV Pro "Office TV"

192.168.4.81 (now .78)

20:f1:b2

Tuya Smart Inc. (block registered Sept 2025)

None (6668 filtered)

Cloud-only Tuya device

192.168.4.44

00:1c:c2

Part II Research, Inc. (2007 registration)

None (~35 probed, all RST)

Unresolved

The Tuya result makes sense in hindsight. That OUI block is less than a year old, and with no local ports and no Home Assistant integration, it's almost certainly something paired through the Smart Life app and left talking to the cloud. The neighbor table also confirmed things I already knew, like my Philips Hue bridge, the Synology NAS, and a Sonos Arc.

Three devices are still hiding, and that's fine

I'll be honest, 192.168.4.44 still hasn't given itself up, and I got it wrong the second time too. Convinced it was the TV, I reran the Cast and AirPlay checks with qm guest exec and got back nothing but a neighbor table entry. The eero app filled in a few blanks: .44 connects only to 2.4 GHz, sits on my kitchen node, and first joined on June 22. Its OUI belongs to Part II Research, the company behind Macally, which doesn't make 2.4 GHz smart home gadgets. An OUI tells you who registered the block, not who built the thing. I can live with three things that I can't quite identify.