bdraco / aiodiscover

Discover Hosts via ARP and PTR lookup

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Support discovery on networks with no PTR records?

nickolay opened this issue · comments

Use Case

I'm looking for a way to have Haier AC wifi adapters auto-discovered in Home Assistant. I was hoping to find candidates by MAC address (04:fa:83:...), then probe them.

I see the ACs in the output of arp -a on my macOS setup:

? (192.168.1.60) at 4:fa:83:8f:84:xx on en0 ifscope [ethernet]
? (192.168.1.67) at 4:fa:83:8f:84:xx on en0 ifscope [ethernet]

..but https://github.com/bdraco/aiodiscover/blob/main/demo.py prints nothing.

Seems like this is because of #1 and my router (Keenetic) not resolving PTR requests (dig -x 192.168.1.60).

I see that all Home Assistant integrations include a hostname/domain filter, but I don't really understand why they have to do that.

Solution

Make the hostname filter optional?

Alternatives

Looking at https://developers.home-assistant.io/docs/network_discovery/ , I tried:

Both seem to work (e.g. my TV is discovered), but the ACs are not there.

We need PTR records to reduce the number of network probes.

You can still add 04:fa:83* to the dhcp discovery in HA and it will still be found when the dhcp request is made or a compatible device tracker integration is installed that knows about the devices on the network (it will just be a bit slower to find it)

Check the broadlink integration for an example of this

Thanks for the super-fast reply!

We need PTR records to reduce the number of network probes.

Would you mind expanding on that, please? In context of a standalone library, when I run demo.py, the hostname filter is applied the last:

for ip, hostname in hostnames.items()
, so the expected reduction must happen elsewhere (somewhere in home assistant perhaps?)

If so, wouldn't it make sense to have the demo print all the neighbours? Especially since you say home assistant will somehow find them anyway?

a compatible device tracker integration is installed that knows about the devices on the network

Not sure what you mean here. Google says there's https://www.home-assistant.io/integrations/device_tracker/ which I didn't examine too closely, but it doesn't seem relevant. I know there's keenetic_ndms2 which "knows" about the ACs on my network, but I didn't expect it to affect DHCP discovery...

Check the broadlink integration for an example of this

I take it you meant https://github.com/home-assistant/core/blob/dev/homeassistant/components/broadlink/manifest.json , which disproves my claim that "all Home Assistant integrations include a hostname/domain filter". Thanks for the pointer, I'll have to dig into this.

Would you mind expanding on that, please? In context of a standalone library, when I run demo.py, the hostname filter is applied the last:

for ip, hostname in hostnames.items()

, so the expected reduction must happen elsewhere (somewhere in home assistant perhaps?)
If so, wouldn't it make sense to have the demo print all the neighbours? Especially since you say home assistant will somehow find them anyway?

We have to send data to every host that isn't in the arp table to populate the mac address. If we didn't filter by has PTR we would have to do that for every host on the network.

https://github.com/bdraco/aiodiscover/blob/main/aiodiscover/network.py#L123

Ah, I think I get what reduction you refer to: before PR #1 async_populate_arp unconditionally probed every possible host (IP) on the network in order to populate the ARP cache. Now the DNS servers are probed instead for the PTR of each possible IP, and async_populate_arp only gets called for the hosts which (1) have PTR records and (2) are not in the ARP cache.

The reason it made zero sense to me was that I had my ARP cache primed. So I thought, "why don't you just loop over arp -a, querying PTR records for the IPs in there?" Now I understand that typically cache would be empty or incomplete.

One thing that's still unclear to me is how big is the problem of probing each possible host on the network. Right now this library's discover_hosts.async_discover() does not work at all on my router (I have yet to see how/if DHCP discovery works in HASS given this). Would falling back to full network scan (on routers such as mine) be a bad idea? On the first glance 255 UDP requests to different hosts' port 80 don't seem to be much worse than 255 DNS requests, but I must be missing something again.