import socket
import struct
dns_cache = {}
def build_dns_query(domain, qtype=1):
# Build a DNS query packet
ID = 1337 # Unique identifier for the query
FLAGS = 0x0100 # Standard query
QDCOUNT = 1 # Number of questions
ANCOUNT = 0 # Number of answers
NSCOUNT = 0 # Number of authority records
ARCOUNT = 0 # Number of additional records
query = struct.pack('!HHHHHH', ID, FLAGS, QDCOUNT, ANCOUNT, NSCOUNT, ARCOUNT)
for part in domain.split('.'):
query += struct.pack('B', len(part)) + part.encode('utf-8')
query += b'\x00' # Null-terminator for domain name
query += struct.pack('!H', qtype) # Query type (A, CNAME, etc.)
query += struct.pack('!H', 1) # Query class IN (Internet)
return query
def parse_dns_response(response):
# Parse DNS response
_, flags, _, ancount, _, _, _, _, _, _, _, _ = struct.unpack('!HHHHHHHHHHHH', response[:24])
# Check if response is valid
if flags & 0x8000 != 0x8000: # Check if it's a response
raise Exception("Not a DNS response")
# Skip questions section
pos = response.find(b'\x00', 24) + 5
# Extract IP addresses, CNAME, and NS IP from answers
ip_addresses = []
cname = None
ns_ip = None
for _ in range(ancount):
_, qtype, _, _, _, data_len = struct.unpack('!HHHHHH', response[pos:pos + 12])
pos += 12
if qtype == 1: # A record
ip = '.'.join(str(byte) for byte in response[pos:pos + data_len])
ip_addresses.append(ip)
elif qtype == 5: # CNAME record
cname = response[pos:pos + data_len]
elif qtype == 2: # NS record
ns_ip = '.'.join(str(byte) for byte in response[pos:pos + data_len])
pos += data_len
return ip_addresses, cname, ns_ip
def resolve_dns(domain):
if domain in dns_cache:
print(f"Using cached result for {domain}")
return dns_cache[domain]
max_iterations = 5
iterations = 0
while iterations < max_iterations:
server = ('8.8.8.8', 53) # Google's public DNS server
query = build_dns_query(domain)
with socket.socket(socket.AF_INET, socket.SOCK_DGRAM) as sock:
sock.sendto(query, server)
response, _ = sock.recvfrom(1024)
ip_addresses, cname, ns_ip = parse_dns_response(response)
if ip_addresses:
dns_cache[domain] = ip_addresses
return ip_addresses
if cname:
domain = cname.decode('utf-8')
elif ns_ip:
server = (ns_ip, 53)
else:
break
iterations += 1
raise Exception("DNS resolution failed after multiple iterations")
def main():
domain = input("Enter domain name: ")
try:
ip_addresses = resolve_dns(domain)
print("\nResolved IP Addresses:")
for ip in ip_addresses:
print(f"{domain} has IP address: {ip}")
except Exception as e:
print(f"An error occurred: {e}")
if __name__ == "__main__":
main()