1. Your program must send DNS queries over UDP to a DNS server using the Python3 programming language and the socket module.
2. Your program must send requests for either IPv4 ("A) or IPv6 ("AAAA") addresses
3. Your program must take 3 command-line arguments:
a. The type of of address requested (denoted with the --type flag), which can have the
value 'A' or 'AAAA'
b. The host name being queried (denoted with the --name flag)
c. The IP address of the DNS server to query (denoted with the --server flag)
4. Your DNS queries should follow the proper endianness standard for a network protocol.
What I have tried:
#!/usr/bin/env python3
# Python DNS query client
# Example usage:
# ./dns.py --type=AAAA --name=www.google.com --server=8.8.8.8
from dns_tools import dns
import argparse
import ctypes
import random
import socket
import struct
import sys
def main():
# Setup configuration
parser = argparse.ArgumentParser(description='DNS client for ECPE 170')
parser.add_argument('--type', action='store', dest='qtype',
required=True, help='Query Type (A or AAAA)')
parser.add_argument('--name', action='store', dest='qname',
required=True, help='Query Name')
parser.add_argument('--server', action='store', dest='server_ip',
required=True, help='DNS Server IP')
args = parser.parse_args()
qtype = args.qtype
qname = args.qname
server_ip = args.server_ip
port = 53
server_address = (server_ip, port)
if qtype not in ("A", "AAAA"):
print("Error: Query Type must be 'A' (IPv4) or 'AAAA' (IPv6)")
sys.exit()
# Create UDP socket
# ---------
# STUDENT TO-DO
# ---------
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect((server_ip, port))
# Generate DNS request message
# ---------
# STUDENT TO-DO
# ---------
#type
raw_bytes = bytearray()
if qtype == 'A':
raw_bytes.append(0x00)
raw_bytes.append(0x01)
elif qtype == 'AAAA':
raw_bytes.append(0x00)
raw_bytes.append(0x1c)
#qname
split = qname.split(".")
string = ""
for i in split:
hexs = hex(len(i))
string += str(hexs)+i
#string += "0x00"
raw_bytes += bytes(string,'ascii')
#sever 8.8.8.8
raw_bytes.append(0x08)
raw_bytes.append(0x08)
raw_bytes.append(0x08)
raw_bytes.append(0x08)
# Send request message to server
# (Tip: Use sendto() function for UDP)
# ---------
# STUDENT TO-DO
# ---------
bytes_send = s.sendto(raw_bytes,server_address)
# Receive message from server
# (Tip: use recvfrom() function for UDP)
# ---------
# STUDENT TO-DO
# ---------
max_bytes = 4096
(raw_bytes2,src_addr) = s.recvfrom(max_bytes)
print(raw_bytes2)
# Close socket
# ---------
# STUDENT TO-DO
# ---------
s.close()
# Decode DNS message and display to screen
dns.decode_dns(raw_bytes)
print(bytes_send)
if __name__ == "__main__":
sys.exit(main())\
COMMAND:
unix> ./dns.py --type=A --name=www.pacific.edu --server=8.8.8.8
WHY IS THIS CODE NOT OUTPUTTING THIS:
Sending request for www.google.com, type AAAA, to server 8.8.8.8, port 53
Server Response
---------------
Message ID: 64164
Response code: No error
Counts: Query 1, Answer 1, Authority 0, Additional 0
Question 1:
Name: www.google.com
Type: AAAA
Class: IN
Answer 1:
Name: 0xc00c
Type: AAAA, Class: IN, TTL: 299
RDLength: 16 bytes
Addr: 2607:f8b0:4005:802::1012 (IPv6)
I KEEP GETTING THIS OUTPUT WHICH IS WRONG:
Server Response
---------------
Message ID: 1
Response code: WARNING: Unknown rcode
Counts: Query 13175, Answer 30583, Authority 12408, Additional 14192
Traceback (most recent call last):
File "./dns.py", line 114, in <module>
sys.exit(main())
File "./dns.py", line 110, in main
dns.decode_dns(raw_bytes)
File "/home/ricardo/bitbucket/2021_spring_ecpe170/lab09/dns_tools.py", line 95, in decode_dns
qname_len = struct.unpack("B",raw_bytes[offset:offset+1])[0]
struct.error: unpack requires a buffer of 1 bytes
PLEASE HELP FIX, THANK YOU.