forked from henices/Tcp-DNS-proxy
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathtcpdns.py
144 lines (124 loc) · 4.18 KB
/
tcpdns.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
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
#! /usr/bin/python
# -*- coding: utf-8 -*-
# cody by zhouzhenster@gmail.com
# ver: 0.2 update 2011-10-23
# use SocketServer to run a multithread udp server
# update:
# 2012-04-16, add more public dns servers support tcp dns query
# 8.8.8.8 google
# 8.8.4.4 google
# 156.154.70.1 Dnsadvantage
# 156.154.71.1 Dnsadvantage
# 208.67.222.222 OpenDNS
# 208.67.220.220 OpenDNS
# 198.153.192.1 Norton
# 198.153.194.1 Norton
import os, sys
import socket
import struct
import threading
import SocketServer
import traceback
import random
DHOSTS = ['156.154.70.1', # remote dns server address list
'8.8.8.8',
'8.8.4.4',
'156.154.71.1',
#'208.67.222.222',
#'208.67.220.220',
#'198.153.192.1',
#'198.153.194.1'
]
DPORT = 53 # default dns port 53
TIMEOUT = 20 # set timeout 5 second
#-------------------------------------------------------------
# Hexdump£¬Cool :)
# default width 16
#--------------------------------------------------------------
def hexdump( src, width=16 ):
FILTER=''.join([(len(repr(chr(x)))==3) and chr(x) or '.' for x in range(256)])
result=[]
for i in xrange(0, len(src), width):
s = src[i:i+width]
hexa = ' '.join(["%02X"%ord(x) for x in s])
printable = s.translate(FILTER)
result.append("%04X %s %s\n" % (i, hexa, printable))
return ''.join(result)
#---------------------------------------------------------------
# bytetodomain
# 03www06google02cn00 => www.google.cn
#--------------------------------------------------------------
def bytetodomain(s):
domain = ''
i = 0
length = struct.unpack('!B', s[0:1])[0]
while length != 0 :
i += 1
domain += s[i:i+length]
i += length
length = struct.unpack('!B', s[i:i+1])[0]
if length != 0 :
domain += '.'
return domain
#--------------------------------------------------
# tcp dns request
#---------------------------------------------------
def QueryDNS(server, port, querydata):
# length
Buflen = struct.pack('!h', len(querydata))
sendbuf = Buflen + querydata
try:
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.settimeout(TIMEOUT) # set socket timeout
s.connect((server, int(port)))
s.send(sendbuf)
data = s.recv(2048)
except:
print traceback.print_exc(sys.stdout)
if s: s.close()
return
if s: s.close()
return data
#-----------------------------------------------------
# send udp dns respones back to client program
#----------------------------------------------------
def transfer(querydata, addr, server):
if not querydata: return
domain = bytetodomain(querydata[12:-4])
qtype = struct.unpack('!h', querydata[-4:-2])[0]
print 'domain:%s, qtype:%x, thread:%d' % \
(domain, qtype, threading.activeCount())
sys.stdout.flush()
choose = random.sample(xrange(len(DHOSTS)), 1)[0]
DHOST = DHOSTS[choose]
response = QueryDNS(DHOST, DPORT, querydata)
if response:
# udp dns packet no length
server.sendto(response[2:], addr)
return
class ThreadedUDPServer(SocketServer.ThreadingMixIn, SocketServer.UDPServer):
def __init__(self, s, t):
SocketServer.UDPServer.__init__(self, s, t)
class ThreadedUDPRequestHandler(SocketServer.BaseRequestHandler):
# Ctrl-C will cleanly kill all spawned threads
daemon_threads = True
# much faster rebinding
allow_reuse_address = True
def handle(self):
data = self.request[0]
socket = self.request[1]
addr = self.client_address
transfer(data, addr, socket)
#------------------------------------------------------
# main entry
#------------------------------------------------------
if __name__ == "__main__":
print '>> Please wait program init....'
print '>> Init finished!'
print '>> Now you can set dns server to 127.0.0.1'
server = ThreadedUDPServer(('127.0.0.1', 53), ThreadedUDPRequestHandler)
# on my ubuntu uid is 1000, change it
# comment out below line on windows platform
#os.setuid(1000)
server.serve_forever()
server.shutdown()