"""
Shared private/internal IP range constants for security validation.

Used by SSRF validation and notification URL validation to avoid
duplicating IP range definitions.
"""

import ipaddress

# RFC1918 private networks + loopback + link-local + CGNAT + IPv6 equivalents
# nosec B104 - These hardcoded IPs are intentional for security validation
PRIVATE_IP_RANGES = [
    ipaddress.ip_network("127.0.0.0/8"),  # IPv4 loopback
    ipaddress.ip_network("::1/128"),  # IPv6 loopback
    ipaddress.ip_network("10.0.0.0/8"),  # RFC1918 Class A private
    ipaddress.ip_network("172.16.0.0/12"),  # RFC1918 Class B private
    ipaddress.ip_network("192.168.0.0/16"),  # RFC1918 Class C private
    ipaddress.ip_network(
        "100.64.0.0/10"
    ),  # CGNAT - used by Podman/rootless containers
    ipaddress.ip_network("169.254.0.0/16"),  # Link-local
    ipaddress.ip_network("fe80::/10"),  # IPv6 link-local
    ipaddress.ip_network("fc00::/7"),  # IPv6 unique local
    ipaddress.ip_network("0.0.0.0/8"),  # "This" network (IPv4 unspecified)
    ipaddress.ip_network(
        "::/128"
    ),  # IPv6 unspecified — Linux routes connections to local host
    # IPv6 transition prefixes that can wrap private IPv4 destinations.
    # On Linux hosts with kernel sit0 / NAT64 routes configured, these
    # prefixes are forwarded to the embedded IPv4 (e.g. 2002:7f00:1::
    # → 127.0.0.1 via 6to4). Default Linux has no such routes so they
    # are not exploitable in the typical deployment, but blocking them
    # closes the gap for operators who do enable transition tunnels.
    ipaddress.ip_network("2002::/16"),  # 6to4 (RFC 3056, deprecated RFC 7526)
    ipaddress.ip_network("64:ff9b::/96"),  # NAT64 well-known prefix (RFC 6052)
    ipaddress.ip_network(
        "64:ff9b:1::/48"
    ),  # NAT64 local-use prefix (RFC 8215) — same SSRF threat class as the WKP
    ipaddress.ip_network("2001::/32"),  # Teredo (RFC 4380)
    ipaddress.ip_network("100::/64"),  # IPv6 discard prefix (RFC 6666)
    # IPv4-Compatible IPv6 — DEPRECATED by RFC 4291 §2.5.5.1 in 2006 but
    # still parseable by ipaddress and routable on hosts with ::/96 routes
    # configured (rare but real). Embeds the IPv4 in the low 32 bits so
    # [::169.254.169.254] would otherwise reach IMDS, identically to the
    # 6to4/NAT64 wraps. Has zero legitimate live use; blocking it is the
    # same defense-in-depth move as the transition prefixes above.
    ipaddress.ip_network("::/96"),
]

# NAT64 prefixes — operators on IPv6-only hosts using DNS64+NAT64 reach
# IPv4 services through these. Blocking by default protects the typical
# deployment shape (laptops / dual-stack) from the IPv6-wrapped IMDS /
# RFC1918 SSRF bypass class. Operators who actually need NAT64 reachable
# can opt in via the env-only setting ``security.allow_nat64``
# (LDR_SECURITY_ALLOW_NAT64=true). 6to4, Teredo, and discard remain
# unconditionally blocked — they have no legitimate live use.
NAT64_PREFIXES = [
    ipaddress.ip_network("64:ff9b::/96"),
    ipaddress.ip_network("64:ff9b:1::/48"),
]
