-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathdummydns.py
executable file
·90 lines (78 loc) · 2.32 KB
/
dummydns.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
#!/usr/bin/env python3
import socket, struct, signal, sys
port = 53
if len(sys.argv) > 1:
port = int(sys.argv[1])
s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
s.bind(("", port))
# Avoid locking up on windows
signal.signal(signal.SIGINT, lambda *_: sys.exit())
s.settimeout(0.1)
def query(name, qtype):
# Put custom domain names here
ip = []
if qtype == 1: # A (ipv4)
if name == "example.com":
ip = [93, 184, 216, 34]
else:
ip = [127, 0, 0, 1]
elif qtype == 28: # AAAA (ipv6)
if name == "example.com":
ip = [0x26, 0x06, 0x28, 0x00, 0x02, 0x20, 0x00, 0x01,
0x02, 0x48, 0x18, 0x93, 0x25, 0xc8, 0x19, 0x46]
else:
ip = [0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01]
print(name, "=", ip)
return bytes(ip)
def make_name(string):
res = bytearray()
for x in string.split("."):
res.append(len(x))
res += x.encode()
res.append(0)
return bytes(res)
def read_name(data, offs):
res = ""
while True:
len = data[offs]
offs += 1
if not len:
break
if res:
res += "."
res += data[offs:offs+len].decode()
offs += len
return res, offs
while True:
try:
mesg, addr = s.recvfrom(512)
except TimeoutError:
continue
id, flags, qdcount, ancount, nscount, arcount = struct.unpack_from("!HHHHHH", mesg, 0)
# Make sure we're receiving a normal query
if (flags & 0xFE8F) != 0:
continue
if qdcount == 0:
continue
# Make result flags
resflags = 0x8000
# If recursion is desired, set it as available
if flags & 0x0100:
resflags |= 0x0180
# Read first query section
qname, offs = read_name(mesg, 12)
qtype, qclass = struct.unpack_from("!HH", mesg, offs)
if qclass != 1 or (qtype != 1 and qtype != 28):
continue
resname = make_name(qname)
resdata = query(qname, qtype)
# Encode result
res = bytearray()
res += struct.pack("!HHHHHH", id, resflags, 1, 1, 0, 0)
res += resname
res += struct.pack("!HH", qtype, qclass)
res += b'\xc0\x0c'
res += struct.pack("!HHIH", qtype, qclass, 0, len(resdata))
res += resdata
s.sendto(res, addr)