Expand network util to check for link local addresses (#33499)
This commit is contained in:
parent
0cf9268ca8
commit
4a32a0f1da
4 changed files with 77 additions and 9 deletions
|
@ -1,5 +1,7 @@
|
|||
"""Config flow to configure Axis devices."""
|
||||
|
||||
from ipaddress import ip_address
|
||||
|
||||
import voluptuous as vol
|
||||
|
||||
from homeassistant import config_entries
|
||||
|
@ -11,6 +13,7 @@ from homeassistant.const import (
|
|||
CONF_PORT,
|
||||
CONF_USERNAME,
|
||||
)
|
||||
from homeassistant.util.network import is_link_local
|
||||
|
||||
from .const import CONF_MODEL, DOMAIN
|
||||
from .device import get_device
|
||||
|
@ -129,7 +132,7 @@ class AxisFlowHandler(config_entries.ConfigFlow, domain=DOMAIN):
|
|||
if serial_number[:6] not in AXIS_OUI:
|
||||
return self.async_abort(reason="not_axis_device")
|
||||
|
||||
if discovery_info[CONF_HOST].startswith("169.254"):
|
||||
if is_link_local(ip_address(discovery_info[CONF_HOST])):
|
||||
return self.async_abort(reason="link_local_address")
|
||||
|
||||
await self.async_set_unique_id(serial_number)
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
"""Config flow for DoorBird integration."""
|
||||
from ipaddress import ip_address
|
||||
import logging
|
||||
import urllib
|
||||
|
||||
|
@ -8,6 +9,7 @@ import voluptuous as vol
|
|||
from homeassistant import config_entries, core, exceptions
|
||||
from homeassistant.const import CONF_HOST, CONF_NAME, CONF_PASSWORD, CONF_USERNAME
|
||||
from homeassistant.core import callback
|
||||
from homeassistant.util.network import is_link_local
|
||||
|
||||
from .const import CONF_EVENTS, DOORBIRD_OUI
|
||||
from .const import DOMAIN # pylint:disable=unused-import
|
||||
|
@ -90,7 +92,7 @@ class ConfigFlow(config_entries.ConfigFlow, domain=DOMAIN):
|
|||
|
||||
if macaddress[:6] != DOORBIRD_OUI:
|
||||
return self.async_abort(reason="not_doorbird_device")
|
||||
if discovery_info[CONF_HOST].startswith("169.254"):
|
||||
if is_link_local(ip_address(discovery_info[CONF_HOST])):
|
||||
return self.async_abort(reason="link_local_address")
|
||||
|
||||
await self.async_set_unique_id(macaddress)
|
||||
|
|
|
@ -1,18 +1,41 @@
|
|||
"""Network utilities."""
|
||||
from ipaddress import IPv4Address, IPv6Address, ip_address, ip_network
|
||||
from ipaddress import IPv4Address, IPv6Address, ip_network
|
||||
from typing import Union
|
||||
|
||||
# IP addresses of loopback interfaces
|
||||
LOCAL_IPS = (ip_address("127.0.0.1"), ip_address("::1"))
|
||||
# RFC6890 - IP addresses of loopback interfaces
|
||||
LOOPBACK_NETWORKS = (
|
||||
ip_network("127.0.0.0/8"),
|
||||
ip_network("::1/128"),
|
||||
ip_network("::ffff:127.0.0.0/104"),
|
||||
)
|
||||
|
||||
# RFC1918 - Address allocation for Private Internets
|
||||
LOCAL_NETWORKS = (
|
||||
# RFC6890 - Address allocation for Private Internets
|
||||
PRIVATE_NETWORKS = (
|
||||
ip_network("fd00::/8"),
|
||||
ip_network("10.0.0.0/8"),
|
||||
ip_network("172.16.0.0/12"),
|
||||
ip_network("192.168.0.0/16"),
|
||||
)
|
||||
|
||||
# RFC6890 - Link local ranges
|
||||
LINK_LOCAL_NETWORK = ip_network("169.254.0.0/16")
|
||||
|
||||
|
||||
def is_loopback(address: Union[IPv4Address, IPv6Address]) -> bool:
|
||||
"""Check if an address is a loopback address."""
|
||||
return any(address in network for network in LOOPBACK_NETWORKS)
|
||||
|
||||
|
||||
def is_private(address: Union[IPv4Address, IPv6Address]) -> bool:
|
||||
"""Check if an address is a private address."""
|
||||
return any(address in network for network in PRIVATE_NETWORKS)
|
||||
|
||||
|
||||
def is_link_local(address: Union[IPv4Address, IPv6Address]) -> bool:
|
||||
"""Check if an address is link local."""
|
||||
return address in LINK_LOCAL_NETWORK
|
||||
|
||||
|
||||
def is_local(address: Union[IPv4Address, IPv6Address]) -> bool:
|
||||
"""Check if an address is local."""
|
||||
return address in LOCAL_IPS or any(address in network for network in LOCAL_NETWORKS)
|
||||
"""Check if an address is loopback or private."""
|
||||
return is_loopback(address) or is_private(address)
|
||||
|
|
40
tests/util/test_network.py
Normal file
40
tests/util/test_network.py
Normal file
|
@ -0,0 +1,40 @@
|
|||
"""Test Home Assistant volume utility functions."""
|
||||
|
||||
from ipaddress import ip_address
|
||||
|
||||
import homeassistant.util.network as network_util
|
||||
|
||||
|
||||
def test_is_loopback():
|
||||
"""Test loopback addresses."""
|
||||
assert network_util.is_loopback(ip_address("127.0.0.2"))
|
||||
assert network_util.is_loopback(ip_address("127.0.0.1"))
|
||||
assert network_util.is_loopback(ip_address("::1"))
|
||||
assert network_util.is_loopback(ip_address("::ffff:127.0.0.0"))
|
||||
assert network_util.is_loopback(ip_address("0:0:0:0:0:0:0:1"))
|
||||
assert network_util.is_loopback(ip_address("0:0:0:0:0:ffff:7f00:1"))
|
||||
assert not network_util.is_loopback(ip_address("104.26.5.238"))
|
||||
assert not network_util.is_loopback(ip_address("2600:1404:400:1a4::356e"))
|
||||
|
||||
|
||||
def test_is_private():
|
||||
"""Test private addresses."""
|
||||
assert network_util.is_private(ip_address("192.168.0.1"))
|
||||
assert network_util.is_private(ip_address("172.16.12.0"))
|
||||
assert network_util.is_private(ip_address("10.5.43.3"))
|
||||
assert network_util.is_private(ip_address("fd12:3456:789a:1::1"))
|
||||
assert not network_util.is_private(ip_address("127.0.0.1"))
|
||||
assert not network_util.is_private(ip_address("::1"))
|
||||
|
||||
|
||||
def test_is_link_local():
|
||||
"""Test link local addresses."""
|
||||
assert network_util.is_link_local(ip_address("169.254.12.3"))
|
||||
assert not network_util.is_link_local(ip_address("127.0.0.1"))
|
||||
|
||||
|
||||
def test_is_local():
|
||||
"""Test local addresses."""
|
||||
assert network_util.is_local(ip_address("192.168.0.1"))
|
||||
assert network_util.is_local(ip_address("127.0.0.1"))
|
||||
assert not network_util.is_local(ip_address("208.5.4.2"))
|
Loading…
Add table
Add a link
Reference in a new issue