Newer
Older
dns_server / test_server.py
import socket
localIP     = "127.0.0.1"
localPort   = 53
bufferSize  = 1024
msgFromServer       = "Hello UDP Client"
bytesToSend         = str.encode(msgFromServer)

# Create a datagram socket
UDPServerSocket = socket.socket(family=socket.AF_INET, type=socket.SOCK_DGRAM)
# Bind to address and ip
UDPServerSocket.bind((localIP, localPort))

 
class DNSQuery:
  def __init__(self, data):
    self.data=data
    self.domain=b''

    type_ = (data[2] >> 3) & 15   # Opcode bits
    if type_ == 0:                     # Standard query
      ini=12
      lon=data[ini]
      while lon != 0:
        self.domain+=data[ini+1:ini+lon+1]+b'.'
        ini+=lon+1
        lon=data[ini]

  def reply(self, ip):
    packet=b''
    if self.domain:
      packet+=self.data[:2] + b"\x81\x80"
      packet+=self.data[4:6] + self.data[4:6] + b'\x00\x00\x00\x00'   # Questions and Answers Counts
      packet+=self.data[12:]                                         # Original Domain Name Question
      packet+=b'\xc0\x0c'                                             # Pointer to domain name
      packet+=b'\x00\x01\x00\x01\x00\x00\x00\x3c\x00\x04'             # Response type, ttl and resource data length -> 4 bytes
      packet+=b''.join(chr(int(i)).encode() for i in ip.split(b'.')) # 4bytes of IP
      print(packet)
    return packet

# Listen for incoming datagrams

while(True):

    bytesAddressPair = UDPServerSocket.recvfrom(bufferSize)

    print(bytesAddressPair)

    message = bytesAddressPair[0]

    address = bytesAddressPair[1]

    clientMsg = "Message from Client:{}".format(message)
    clientIP  = "Client IP Address:{}".format(address)

    pkt = DNSQuery(message)
    reply = pkt.reply(b'8.8.8.8')
    
    
    print(clientMsg)
    print(clientIP)

   

    # Sending a reply to client

    UDPServerSocket.sendto(reply, address)