1 """Network helper class for the network integration."""
3 from __future__
import annotations
5 from ipaddress
import IPv4Address, IPv6Address, ip_address
8 from typing
import cast
14 from .const
import MDNS_TARGET_IP
15 from .models
import Adapter, IPv4ConfiguredAddress, IPv6ConfiguredAddress
17 _LOGGER = logging.getLogger(__name__)
23 source_ip_address = ip_address(source_ip)
if source_ip
else None
25 ha_adapters: list[Adapter] = [
27 for adapter
in ifaddr.get_adapters()
30 if not any(adapter[
"default"]
and adapter[
"auto"]
for adapter
in ha_adapters):
31 for adapter
in ha_adapters:
33 adapter[
"auto"] =
True
38 def enable_adapters(adapters: list[Adapter], enabled_interfaces: list[str]) -> bool:
39 """Enable configured adapters."""
42 if not enabled_interfaces:
46 for adapter
in adapters:
47 if adapter[
"name"]
in enabled_interfaces:
48 adapter[
"enabled"] =
True
55 """Enable auto detected adapters."""
57 adapters, [adapter[
"name"]
for adapter
in adapters
if adapter[
"auto"]]
62 """Adapter has a non-loopback and non-link-local address."""
76 not ip_addr.is_multicast
77 and not ip_addr.is_loopback
78 and not ip_addr.is_link_local
83 for adapter
in adapters:
84 adapter[
"enabled"] =
False
88 adapter: ifaddr.Adapter, next_hop_address: IPv4Address | IPv6Address |
None
90 """Convert an ifaddr adapter to ha."""
91 ip_v4s: list[IPv4ConfiguredAddress] = []
92 ip_v6s: list[IPv6ConfiguredAddress] = []
96 for ip_config
in adapter.ips:
98 ip_addr = ip_address(ip_config.ip[0])
101 assert not isinstance(ip_config.ip, tuple)
102 ip_addr = ip_address(ip_config.ip)
105 if ip_addr == next_hop_address:
111 "name": adapter.nice_name,
112 "index": adapter.index,
122 assert isinstance(ip_config.ip, tuple)
124 "address": ip_config.ip[0],
125 "flowinfo": ip_config.ip[1],
126 "scope_id": ip_config.ip[2],
127 "network_prefix": ip_config.network_prefix,
132 assert not isinstance(ip_config.ip, tuple)
134 "address": ip_config.ip,
135 "network_prefix": ip_config.network_prefix,
141 """Return the source ip that will reach target_ip."""
142 test_sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
143 test_sock.setblocking(
False)
145 test_sock.connect((target_ip, 1))
146 return cast(str, test_sock.getsockname()[0])
150 "The system could not auto detect the source ip for %s on your"
list[Adapter] async_load_adapters()
None _reset_enabled_adapters(list[Adapter] adapters)
bool _adapter_has_external_address(Adapter adapter)
str|None async_get_source_ip(str target_ip)
IPv4ConfiguredAddress _ip_v4_from_adapter(ifaddr.IP ip_config)
bool enable_adapters(list[Adapter] adapters, list[str] enabled_interfaces)
bool _has_external_address(str ip_str)
Adapter _ifaddr_adapter_to_ha(ifaddr.Adapter adapter, IPv4Address|IPv6Address|None next_hop_address)
None enable_auto_detected_adapters(list[Adapter] adapters)
bool _ip_address_is_external(IPv4Address|IPv6Address ip_addr)
IPv6ConfiguredAddress _ip_v6_from_adapter(ifaddr.IP ip_config)