94 lines
2.1 KiB
Python
94 lines
2.1 KiB
Python
# DNScope-reduced/utils/helpers.py
|
|
|
|
import ipaddress
|
|
from typing import Union
|
|
|
|
def _is_valid_domain(domain: str) -> bool:
|
|
"""
|
|
Basic domain validation.
|
|
|
|
Args:
|
|
domain: Domain string to validate
|
|
|
|
Returns:
|
|
True if domain appears valid
|
|
"""
|
|
if not domain or len(domain) > 253:
|
|
return False
|
|
|
|
# Check for valid characters and structure
|
|
parts = domain.split('.')
|
|
if len(parts) < 2:
|
|
return False
|
|
|
|
for part in parts:
|
|
if not part or len(part) > 63:
|
|
return False
|
|
if not part.replace('-', '').replace('_', '').isalnum():
|
|
return False
|
|
|
|
return True
|
|
|
|
def _is_valid_ip(ip: str) -> bool:
|
|
"""
|
|
IP address validation supporting both IPv4 and IPv6.
|
|
|
|
Args:
|
|
ip: IP address string to validate
|
|
|
|
Returns:
|
|
True if IP appears valid (IPv4 or IPv6)
|
|
"""
|
|
if not ip:
|
|
return False
|
|
|
|
try:
|
|
# This handles both IPv4 and IPv6 validation
|
|
ipaddress.ip_address(ip.strip())
|
|
return True
|
|
except (ValueError, AttributeError):
|
|
return False
|
|
|
|
def is_valid_target(target: str) -> bool:
|
|
"""
|
|
Checks if the target is a valid domain or IP address (IPv4/IPv6).
|
|
|
|
Args:
|
|
target: The target string to validate.
|
|
|
|
Returns:
|
|
True if the target is a valid domain or IP, False otherwise.
|
|
"""
|
|
return _is_valid_domain(target) or _is_valid_ip(target)
|
|
|
|
def get_ip_version(ip: str) -> Union[int, None]:
|
|
"""
|
|
Get the IP version (4 or 6) of a valid IP address.
|
|
|
|
Args:
|
|
ip: IP address string
|
|
|
|
Returns:
|
|
4 for IPv4, 6 for IPv6, None if invalid
|
|
"""
|
|
try:
|
|
addr = ipaddress.ip_address(ip.strip())
|
|
return addr.version
|
|
except (ValueError, AttributeError):
|
|
return None
|
|
|
|
def normalize_ip(ip: str) -> Union[str, None]:
|
|
"""
|
|
Normalize an IP address to its canonical form.
|
|
|
|
Args:
|
|
ip: IP address string
|
|
|
|
Returns:
|
|
Normalized IP address string, None if invalid
|
|
"""
|
|
try:
|
|
addr = ipaddress.ip_address(ip.strip())
|
|
return str(addr)
|
|
except (ValueError, AttributeError):
|
|
return None |