"""Network address helpers, backed by the stdlib ``ipaddress`` module. The bash prototype hand-rolled integer/CIDR math; here we lean on ``ipaddress`` for correct handling of private ranges, link-local, CGNAT, and IPv6. """ from __future__ import annotations import ipaddress from collections.abc import Iterable def parse_addr(addr: str) -> ipaddress._BaseAddress | None: """Parse an address that may carry a ``%iface`` zone or ``[..]`` brackets.""" if not addr: return None addr = addr.strip().strip("[]") addr = addr.split("%", 1)[0] # drop IPv6 zone id try: return ipaddress.ip_address(addr) except ValueError: return None def is_public_ip(addr: str) -> bool: """True if ``addr`` is a globally-routable address. Excludes loopback, RFC1918 private, link-local, CGNAT (100.64/10), and other non-global ranges — i.e. a connection to such an address is one that actually leaves the host to the public internet. """ ip = parse_addr(addr) if ip is None: return False return ip.is_global def ip_in_cidrs(addr: str, cidrs: Iterable[str]) -> bool: """True if ``addr`` falls inside any CIDR in ``cidrs`` (the trust list).""" ip = parse_addr(addr) if ip is None: return False for cidr in cidrs: cidr = cidr.strip() if not cidr: continue try: net = ipaddress.ip_network(cidr, strict=False) except ValueError: continue if ip.version == net.version and ip in net: return True return False def split_host_port(endpoint: str) -> tuple[str, str]: """Split an ``ss`` endpoint like ``10.0.0.2%eth0:443`` or ``[::1]:22``.""" endpoint = endpoint.strip() if endpoint.startswith("["): host, _, port = endpoint.partition("]") return host.lstrip("["), port.lstrip(":") host, _, port = endpoint.rpartition(":") return host, port