8 def socks4AResolveRequest(hostname
):
14 reqheader
= struct
.pack("!BBHL", version
, command
, port
, addr
)
15 return "%s%s\x00%s\x00"%(reqheader
,username
,hostname
)
17 def socks4AParseResponse(response
):
19 if len(response
) < RESPONSE_LEN
:
21 assert len(response
) >= RESPONSE_LEN
22 version
,status
,port
= struct
.unpack("!BBH",response
[:4])
26 return "%d.%d.%d.%d"%tuple(map(ord, response
[4:]))
28 return "ERROR (status %d)"%status
32 def socks5ParseHello(response
):
33 if response
!= "\x05\x00":
34 raise ValueError("Bizarre socks5 response")
35 def socks5ResolveRequest(hostname
):
41 reqheader
= struct
.pack("!BBBBB",version
, command
, rsv
, atype
, len(hostname
))
42 portstr
= struct
.pack("!H",port
)
43 return "%s%s%s"%(reqheader
,hostname
,portstr
)
44 def socks5ParseResponse(r
):
47 version
, reply
, rsv
, atype
= struct
.unpack("!BBBB",r
[:4])
52 assert atype
in (0x01,0x04)
53 expected_len
= 4 + ({1:4,4:16}[atype
]) + 2
54 if len(r
) < expected_len
:
56 elif len(r
) > expected_len
:
57 raise ValueError("Overlong socks5 reply!")
60 return "%d.%d.%d.%d"%tuple(map(ord,addr
))
62 # not really the right way to format IPv6
63 return "IPv6: %s"%(":".join([hex(ord(c
)) for c
in addr
]))
65 def parseHostAndPort(h
):
66 host
, port
= "localhost", 9050
73 print "Bad hostname %r"%h
83 def resolve(hostname
, sockshost
, socksport
, socksver
=4):
84 assert socksver
in (4,5)
86 fmt
= socks4AResolveRequest
87 parse
= socks4AParseResponse
89 fmt
= socks5ResolveRequest
90 parse
= socks5ParseResponse
91 s
= socket
.socket(socket
.AF_INET
, socket
.SOCK_STREAM
)
92 s
.connect((sockshost
,socksport
))
95 socks5ParseHello(s
.recv(2))
96 print len(fmt(hostname
)), len(hostname
)
99 result
= parse(answer
)
100 while result
is None:
105 result
= parse(answer
)
106 print "Got answer",result
109 print "Got extra data too: %r"%m
112 if __name__
== '__main__':
113 if len(sys
.argv
) not in (2,3,4):
114 print "Syntax: resolve.py [-4|-5] hostname [sockshost:socksport]"
117 if sys
.argv
[1] in ("-4", "-5"):
118 socksver
= int(sys
.argv
[1][1])
120 if len(sys
.argv
) == 4:
121 print "Syntax: resolve.py [-4|-5] hostname [sockshost:socksport]"
123 if len(sys
.argv
) == 3:
124 sh
,sp
= parseHostAndPort(sys
.argv
[2])
126 sh
,sp
= parseHostAndPort("")
127 resolve(sys
.argv
[1], sh
, sp
, socksver
)