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 |