.
Hab ihn mal schnell überarbeitet, Enable Explicit - kompatibel und ein paar andere Späße:
Code: Alles auswählen
; EnableExplicit
; InitNetwork()
Procedure IsIP(ip.s)
Protected count, ret, i, a$, va
;ReturnValues :
;0 = no ip
;1 = IPv4 - IP
;2 = IPv6 - IP
count = CountString(ip, ".")
If count = 3
ret = 1
ElseIf count = 5
ret = 2
Else
ProcedureReturn 0
EndIf
For i = 0 To count
a$ = StringField(ip, i + 1, ".")
va = Val(a$)
If a$ = "" Or Str(va)<>a$ Or va>255 Or va<0
ProcedureReturn 0
EndIf
Next i
ProcedureReturn ret
EndProcedure
; führt einen DNS - Lockup aus
Procedure DNS_Lookup(Host$)
Protected ret, *host.hostent
*host = gethostbyname_(host$)
If *host
ret = PeekL(PeekL(*host\h_addr_list))
Else
ret = *host
EndIf
ProcedureReturn ret
EndProcedure
Structure ByteArray
*b.b[0]
EndStructure
Procedure Proxy_Connect(proxy_ip.s, proxy_port.l, ip_to_connect.s, port_to_connect.l, type.l, username.s, userpass.s, timeout.l)
Protected *buffer.ByteArray, netid, text$, user$, length, encoded$, check_timeout, Content$, Result, i, a$
Protected hi, lo, ver, CD, Port, method, k, cont, reply, reserved, atyp, passver, status, cnts
;proxy_ip = IP or URL of the Proxy-Server
;proxy_port = Port of the Proxy-Server
;ip_to_connect = IP or URL of where you want to connect through proxy. ATTENTION:
; SOCKS4 only supports IP in IPv4-format! You have to get the IP first before using this on urls, otherwise it will fail!
;port_to_connect = Port of where you want to connect through proxy
;type = 0 -> http-proxy
;type = 1 -> socks4-proxy
;type = 2 -> socks5-proxy
;If no authorization is needed set username and userpass = ""
;timeout -> Time after connection-trial will time out (in SECONDS)
;Return-Value = 0 -> error ; Return-Value > 0 -> ConnectionID
proxy_ip = IPString(DNS_Lookup(proxy_ip))
ip_to_connect = IPString(DNS_Lookup(ip_to_connect))
*buffer = AllocateMemory(1024)
If *buffer = 0
ProcedureReturn #False
EndIf
netid = OpenNetworkConnection(proxy_ip, proxy_port)
If netid = 0
FreeMemory(*buffer)
ProcedureReturn #False
EndIf
Select type
Case 0
;====================
;HTTP-Proxy
;====================
;Based on Num3's http-proxy-snippet , THX! ->
;http://purebasic.myforums.net/viewtopic.php?t=10327
text$ = "CONNECT " + ip_to_connect + ":" + Str(port_to_connect) + " HTTP/1.0" + #CRLF$
If username And userpass
user$ = username + ":" + userpass
length = Len(user$)*2
If length<64
length = 64
EndIf
Base64Encoder(@user$, Len(user$), *buffer, length)
encoded$ = PeekS(*buffer)
text$ + "Authorization: Basic " + encoded$ + #CRLF$
text$ + "Proxy-Authorization: Basic " + encoded$ + #CRLF$
EndIf
text$ + #CRLF$
SendNetworkData(netid, @text$, Len(text$))
check_timeout = ElapsedMilliseconds() + (timeout*1000) ; Timeout
Repeat
Delay(10)
If NetworkClientEvent(netid) = #PB_NetworkEvent_Data
Content$ = Space(14500)
length = ReceiveNetworkData(netid, @Content$, 14500)
While length = 14500
;Clear Input-Buffer
length = ReceiveNetworkData(netid, *buffer, 14500)
Wend
Break
EndIf
Until check_timeout<ElapsedMilliseconds()
Result = 0
cnts = CountString(Content$, Chr(10))
For i = 1 To cnts
a$ = Trim(StringField(Content$, i, Chr(10)))
If Left(a$, 7) = "HTTP/1."
Result = Val(StringField(Content$, 2, Chr(32)))
Break
EndIf
Next i
If check_timeout<ElapsedMilliseconds() Or Result<>200
FreeMemory(*buffer)
CloseNetworkConnection(netid)
ProcedureReturn #False
EndIf
FreeMemory(*buffer)
ProcedureReturn netid
Case 1
;====================
;Socks4 - Proxy
;====================
;Socks4 only supports IPv4 !
;You have to do a DNS-Lookup before using this on urls, otherwise it will fail!
If IsIP(ip_to_connect)<>1
FreeMemory(*buffer)
CloseNetworkConnection(netid)
ProcedureReturn #False
EndIf
;Phase 1 SOCK4
;Send Request
*buffer\b[0] = 4
*buffer\b[1] = 1
hi = Int(port_to_connect/256)
lo = port_to_connect-(256*hi)
*buffer\b[2] = hi
*buffer\b[3] = lo
For i = 1 To 4
*buffer\b[3 + i] = Val(StringField(ip_to_connect, i, ".")) & 255
Next i
PokeS(*buffer + 8, username)
length = 9 + Len(username)
SendNetworkData(netid, *buffer, length)
;Check if connection is established
check_timeout = ElapsedMilliseconds() + (timeout*1000)
Repeat
Delay(10)
If NetworkClientEvent(netid) = #PB_NetworkEvent_Data
ReceiveNetworkData(netid, *buffer, 1024)
ver = *buffer\b[0] & 255
CD = *buffer\b[1] & 255
port = (*buffer\b[2] & 255)*256
Break
EndIf
Until check_timeout<ElapsedMilliseconds()
If check_timeout<ElapsedMilliseconds() Or ver<>0 Or CD<>90
FreeMemory(*buffer)
CloseNetworkConnection(netid)
ProcedureReturn #False
EndIf
;IP and Port should be the same like ip_to_connect/port_to_connect and is just for information
FreeMemory(*buffer)
ProcedureReturn netid
Case 2
;====================
;Socks5 - Proxy
;====================
;Phase 1 SOCK5
;Send wished method
If username = "" And userpass = ""
length = 3
*buffer\b[0] = 5
*buffer\b[1] = 1
*buffer\b[2] = 0
Else
length = 4
*buffer\b[0] = 5
*buffer\b[1] = 2
*buffer\b[2] = 0
*buffer\b[3] = 2
EndIf
SendNetworkData(netid, *buffer, length)
;Check if method is allowed
check_timeout = ElapsedMilliseconds() + (timeout*1000)
Repeat
Delay(10)
If NetworkClientEvent(netid) = 2
ReceiveNetworkData(netid, *buffer, 2)
ver = *buffer\b[0] & 255
method = *buffer\b[1] & 255
Break
EndIf
Until check_timeout<ElapsedMilliseconds()
If check_timeout<ElapsedMilliseconds() Or ver<>5 Or method = 255
FreeMemory(*buffer)
CloseNetworkConnection(netid)
ProcedureReturn #False
EndIf
If method = 2
;Phase 2 SOCK5
;Send Username/Password (if allowed)
*buffer\b[0] = 1
*buffer\b[1] = Len(username)
PokeS(*buffer + 2, username)
k = 2 + Len(username)
*buffer\b[k] = Len(userpass)
PokeS(*buffer + k + 1, userpass)
SendNetworkData(netid, *buffer, Len(userpass) + 1 + k)
;Check if Username/Password is accepted
check_timeout = ElapsedMilliseconds() + (timeout*1000)
Repeat
Delay(10)
If NetworkClientEvent(netid) = #PB_NetworkEvent_Data
ReceiveNetworkData(netid, *buffer, 2)
passver = *buffer\b[0] & 255
status = *buffer\b[1] & 255
Break
EndIf
Until check_timeout<ElapsedMilliseconds()
If check_timeout<ElapsedMilliseconds() Or passver<>1 Or status<>0
FreeMemory(*buffer)
CloseNetworkConnection(netid)
ProcedureReturn #False
EndIf
EndIf
;Phase 3 SOCK5
;Send Connect-Request
*buffer\b[0] = 5
*buffer\b[1] = 1
*buffer\b[2] = 0
Select IsIP(ip_to_connect)
Case 0
*buffer\b[3] = 4
*buffer\b[4] = Len(ip_to_connect)
cnts = Len(ip_to_connect)
For i = 1 To cnts
*buffer\b[4 + i] = Asc(Mid(ip_to_connect, i, 1))
Next i
cont = 4 + i
Case 1
*buffer\b[3] = 1
For i = 1 To 4
*buffer\b[3 + i] = Val(StringField(ip_to_connect, i, ".")) & 255
Next i
cont = 8
Case 2
*buffer\b[3] = 4
For i = 1 To 6
*buffer\b[3 + i] = Val(StringField(ip_to_connect, i, ".")) & 255
Next i
cont = 10
EndSelect
hi = Int(port_to_connect/256)
lo = port_to_connect-(256*hi)
*buffer\b[cont] = hi
*buffer\b[cont + 1] = lo
SendNetworkData(netid, *buffer, cont + 2)
;Now Check the reply
check_timeout = ElapsedMilliseconds() + (timeout*1000)
Repeat
Delay(10)
If NetworkClientEvent(netid) = #PB_NetworkEvent_Data
length = ReceiveNetworkData(netid, *buffer, 1024)
ver = *buffer\b[0] & 255
reply = *buffer\b[1] & 255
reserved = *buffer\b[2] & 255
atyp = *buffer\b[3] & 255
Break
EndIf
Until check_timeout<ElapsedMilliseconds()
If check_timeout<ElapsedMilliseconds() Or ver<>5 Or reply<>0 Or reserved<>0
FreeMemory(*buffer)
CloseNetworkConnection(netid)
ProcedureReturn #False
EndIf
FreeMemory(*buffer)
ProcedureReturn netid
EndSelect
EndProcedure