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
:
20 print "return none", len(response
)
22 assert len(response
) >= RESPONSE_LEN
23 version
,status
,port
= struct
.unpack("!BBH",response
[:4])
27 return "%d.%d.%d.%d"%tuple(map(ord, response
[4:]))
29 return "ERROR (status %d)"%status
33 def socks5ParseHello(response
):
34 if response
!= "\x05\x00":
35 raise ValueError("Bizarre socks5 response")
36 def socks5ResolveRequest(hostname
):
42 reqheader
= struct
.pack("!BBBB",version
, command
, rsv
, atype
)
43 portstr
= struct
.pack("!H",port
)
44 return "%s%s\0%s"%(reqheader
,hostname
,port
)
45 def socks5ParseResponse(r
):
46 if len(r
)<8: return None
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 socksParseHello(s
.recv(2))
98 result
= parse(answer
)
102 print "Connection closed; dying."
105 result
= parse(answer
)
106 print "Got answer",result
109 print "Got extra data too! Ick."
112 if __name__
== '__main__':
113 if len(sys
.argv
) not in (2,3,4):
114 print "Syntax: resolve.py [-4|-5] hostname [sockshost:socksport]"
116 if sys
.argv
[1] in ("-4", "-5"):
117 socksver
= int(sys
.argv
[1][1])
119 if len(sys
.argv
) == 4:
120 print "Syntax: resolve.py [-4|-5] hostname [sockshost:socksport]"
122 if len(sys
.argv
) == 3:
123 sh
,sp
= parseHostAndPort(sys
.argv
[2])
125 sh
,sp
= parseHostAndPort("")
126 resolve(sys
.argv
[1], sh
, sp
)