-
-
Notifications
You must be signed in to change notification settings - Fork 339
/
DNSServer.py
117 lines (100 loc) · 3.56 KB
/
DNSServer.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
# !/usr/bin/env python
# -*- coding: utf-8 -*-
import socketserver
import struct
from Web.DatabaseHub import DomainNameSystemLog
from ClassCongregation import ErrorLog
from config import server_ip
# DNS Query
class DNSQuery:
def __init__(self, data):
i = 1
self.name = ''
while True:
d = int(data[i])
if d == 0:
break
if d < 32:
self.name = self.name + '.'
else:
self.name = self.name + chr(d)
i = i + 1
self.querybytes = data[0:i + 1]
(self.type, self.classify) = struct.unpack('>HH', data[i + 1:i + 5])
self.len = i + 5
def getbytes(self):
return self.querybytes + struct.pack('>HH', self.type, self.classify)
# DNS Answer RRS
class DNSAnswer:
def __init__(self, ip):
self.name = 49164
self.type = 1
self.classify = 1
self.timetolive = 190
self.datalength = 4
self.ip = ip
def getbytes(self):
try:
res = struct.pack('>HHHLH', self.name, self.type, self.classify, self.timetolive, self.datalength)
s = self.ip.split('.')
res = res + struct.pack('BBBB', int(s[0]), int(s[1]), int(s[2]), int(s[3]))
return res
except Exception as e:
ErrorLog().Write(e)
# DNS frame
class DNSFrame:
def __init__(self, data):
(self.id, self.flags, self.quests, self.answers, self.author, self.addition) = struct.unpack('>HHHHHH',
data[0:12])
self.query = DNSQuery(data[12:])
def getname(self):
return self.query.name
def setip(self, ip):
self.answer = DNSAnswer(ip)
self.answers = 1
self.flags = 33152
def getbytes(self):
try:
res = struct.pack('>HHHHHH', self.id, self.flags, self.quests, self.answers, self.author, self.addition)
res = res + self.query.getbytes()
if self.answers != 0:
res = res + self.answer.getbytes()
return res
except Exception as e:
ErrorLog().Write(e)
# A UDPHandler to handle DNS query
class DNSUDPHandler(socketserver.BaseRequestHandler):
def handle(self):
try:
data = self.request[0].strip()
dns = DNSFrame(data)
socket = self.request[1]
namemap = DNSServer.namemap
if (dns.query.type == 1):
# If this is query a A record, thenresponse it
name = dns.getname()
toip = namemap['*']
dns.setip(toip)
DomainNameSystemLog().Write(ip=self.client_address[0],domain_name=name,type="dns",response="",request="")
#print('%s:%s-->%s' % (self.client_address[0], name, toip))
socket.sendto(dns.getbytes(), self.client_address)
else:
# If this is notquery a A record, ignore it
socket.sendto(data, self.client_address)
except Exception as e:
ErrorLog().Write(e)
# DNS Server
class DNSServer:
def __init__(self, port=53):
DNSServer.namemap = {}
self.port = port
def addname(self, name, ip):
DNSServer.namemap[name] = ip
def start(self):
HOST, PORT = "0.0.0.0", self.port
server = socketserver.UDPServer((HOST, PORT), DNSUDPHandler)
server.serve_forever()
if __name__ == '__main__':
sev = DNSServer()
sev.addname('*', server_ip) # default address
sev.start()