DNS resolver with multiple resolution methods
| 24 | |
| 25 | |
| 26 | class DNSResolver: |
| 27 | """DNS resolver with multiple resolution methods""" |
| 28 | |
| 29 | def __init__(self, dns_server=None, max_threads=10, use_tcp=False): |
| 30 | self.dns_server = dns_server |
| 31 | self.max_threads = max_threads |
| 32 | self.use_tcp = use_tcp |
| 33 | |
| 34 | def test_connectivity(self, hostname): |
| 35 | """Test if computer is reachable via ping""" |
| 36 | try: |
| 37 | # Use ping command (works on both Windows and Linux) |
| 38 | ping_cmd = ['ping', '-c', '1', '-W', '2', hostname] # Linux/Mac |
| 39 | import sys |
| 40 | if sys.platform.startswith('win'): |
| 41 | ping_cmd = ['ping', '-n', '1', '-w', '2000', hostname] # Windows |
| 42 | |
| 43 | result = subprocess.run(ping_cmd, capture_output=True, text=True, timeout=5) |
| 44 | return result.returncode == 0 |
| 45 | except (subprocess.TimeoutExpired, subprocess.SubprocessError): |
| 46 | return False |
| 47 | |
| 48 | def _is_valid_ip(self, ip_str): |
| 49 | """Check if IP address is valid and not multicast/reserved""" |
| 50 | try: |
| 51 | import ipaddress |
| 52 | ip = ipaddress.IPv4Address(ip_str) |
| 53 | |
| 54 | # Filter out invalid/reserved addresses |
| 55 | if ip.is_multicast: # 224.0.0.0/4 |
| 56 | #logger.warning(f"⚠️ Filtered multicast IP: {ip_str} (common with proxychains - DNS through proxy may fail)") |
| 57 | return False |
| 58 | if ip.is_loopback: # 127.0.0.0/8 |
| 59 | logger.debug(f"Filtered out loopback IP: {ip_str}") |
| 60 | return False |
| 61 | if ip.is_link_local: # 169.254.0.0/16 |
| 62 | logger.debug(f"Filtered out link-local IP: {ip_str}") |
| 63 | return False |
| 64 | if ip.is_reserved: # Reserved ranges |
| 65 | logger.debug(f"Filtered out reserved IP: {ip_str}") |
| 66 | return False |
| 67 | if str(ip) == '0.0.0.0': |
| 68 | logger.debug(f"Filtered out zero IP: {ip_str}") |
| 69 | return False |
| 70 | |
| 71 | return True |
| 72 | except Exception as e: |
| 73 | logger.debug(f"Invalid IP format: {ip_str} - {e}") |
| 74 | return False |
| 75 | |
| 76 | def resolve_single_computer(self, computer, test_connectivity=False): |
| 77 | """Enhanced IP resolution for a single computer using multiple methods""" |
| 78 | hostname = computer['dns_hostname'] if computer['dns_hostname'] else computer['computer_name'] |
| 79 | if not hostname: |
| 80 | return {'ips': [], 'methods': [], 'connectivity': 'Unknown', 'timestamp': datetime.now().strftime('%Y-%m-%d %H:%M:%S')} |
| 81 | |
| 82 | logger.debug(f"Resolving: {hostname}") |
| 83 | computer_ips = [] |
no outgoing calls
no test coverage detected