202 lines
5.0 KiB
Plaintext
202 lines
5.0 KiB
Plaintext
option casemap:none
|
|
option literals:on
|
|
|
|
ifndef __SOCKET_CLASS__
|
|
__SOCKET_CLASS__ equ 1
|
|
if @Platform eq windows64
|
|
|
|
WSADATA struct
|
|
wVersion dw ?
|
|
wHighVersion dw ?
|
|
iMaxSockets dw ?
|
|
iMaxUdpDg dw ?
|
|
szDescription db 256 dup (?)
|
|
szSystemStatus db 128 dup (?)
|
|
lpVendorInfo dq ?
|
|
WSADATA ends
|
|
|
|
option dllimport:<kernel32>
|
|
ExitProcess proto :word
|
|
HeapAlloc proto :qword, :dword, :qword
|
|
HeapFree proto :qword, :dword, :qword
|
|
GetProcessHeap proto
|
|
|
|
option dllimport:<ws2_32>
|
|
WSAStartup proto :word, :qword
|
|
WSACleanup proto :qword
|
|
closesocket proto :dword
|
|
|
|
option dllimport:none
|
|
exit equ ExitProcess
|
|
close equ closesocket
|
|
|
|
elseif @Platform eq linux64
|
|
malloc proto SYSTEMV :qword
|
|
free proto SYSTEMV :qword
|
|
close proto SYSTEMV :dword
|
|
exit proto SYSTEMV :dword
|
|
|
|
endif
|
|
|
|
memset proto :qword, :dword, :dword
|
|
printf proto :qword, :vararg
|
|
strlen proto :qword
|
|
getaddrinfo proto :qword, :qword, :qword, :qword
|
|
gai_strerror proto :dword
|
|
send proto :dword, :qword, :qword, :dword
|
|
recv proto :dword, :qword, :qword, :dword
|
|
socket proto :dword, :dword, :dword
|
|
connect proto :dword, :qword, :dword
|
|
freeaddrinfo proto :qword
|
|
|
|
CLASS socket_class
|
|
CMETHOD conn
|
|
CMETHOD write
|
|
CMETHOD read
|
|
ENDMETHODS
|
|
if @Platform eq windows64
|
|
wsa WSADATA <?>
|
|
endif
|
|
sock dd 0
|
|
pai dq 0
|
|
hostname dq ?
|
|
port dq ?
|
|
ENDCLASS
|
|
|
|
METHOD socket_class, Init, <VOIDARG>, <>, h:qword, p:qword
|
|
mov rbx, thisPtr
|
|
assume rbx:ptr socket_class
|
|
mov rax, h
|
|
mov [rbx].hostname, rax
|
|
mov rax, p
|
|
mov [rbx].port, rax
|
|
mov rax, rbx
|
|
assume rbx:nothing
|
|
ret
|
|
ENDMETHOD
|
|
|
|
METHOD socket_class, conn, <dword>, <>
|
|
local ht:qword
|
|
|
|
mov rbx, thisPtr
|
|
assume rbx:ptr socket_class
|
|
invoke printf, CSTR("--> Attempting connection to %s on %s",10), [rbx].hostname ,[rbx].port
|
|
if @Platform eq windows64
|
|
invoke WSAStartup, 202h, addr [rbx].wsa
|
|
endif
|
|
invoke memset, ht, 0, 0x30 ;; sizeof(struct addrinfo)
|
|
mov rax, ht
|
|
mov dword ptr [rax], 0 ;; ai_flags
|
|
mov dword ptr [rax+4], AF_INET
|
|
mov dword ptr [rax+8], SOCK_STREAM
|
|
invoke getaddrinfo, [rbx].hostname, [rbx].port, ht, addr [rbx].pai
|
|
.if rax != 0
|
|
invoke gai_strerror, eax
|
|
invoke printf, CSTR("--> Gai_strerror returned: %s",10), rax
|
|
mov rax, -1
|
|
jmp _exit
|
|
.endif
|
|
mov rax, [rbx].pai
|
|
mov edx, dword ptr [rax + 0XC] ;; pai.ai_protocol
|
|
mov ecx, dword ptr [rax + 8] ;; pai.ai_socktype
|
|
mov eax, dword ptr [rax + 4] ;; pai.ai_family
|
|
invoke socket, eax, ecx, edx
|
|
.if rax == -1
|
|
mov rax, -1
|
|
jmp _exit
|
|
.endif
|
|
mov [rbx].sock, eax
|
|
invoke printf, CSTR("--> Socket created as: %d",10), [rbx].sock
|
|
mov rax, [rbx].pai
|
|
mov edx, dword ptr [rax + 0x10] ;; pai.ai_addrlen
|
|
mov rcx, qword ptr [rax + 0x18] ;; pai.ai_addr
|
|
invoke connect, [rbx].sock, rcx, edx
|
|
.if rax == -1
|
|
invoke printf, CSTR("--> connect failed.. %i",10), rax
|
|
mov rax, -1
|
|
jmp _exit
|
|
.endif
|
|
mov rax, 0
|
|
|
|
_exit:
|
|
assume rbx:nothing
|
|
ret
|
|
ENDMETHOD
|
|
|
|
METHOD socket_class, write, <dword>, <>, b:qword
|
|
local tmp:qword
|
|
|
|
mov rbx, thisPtr
|
|
assume rbx:ptr socket_class
|
|
mov rax, b
|
|
mov tmp, rax
|
|
invoke strlen, tmp
|
|
mov rdx, rax
|
|
invoke send, [rbx].sock, tmp, rdx, 0
|
|
.if eax == -1
|
|
invoke printf, CSTR("--> Error in send..%d",10), rax
|
|
ret
|
|
.endif
|
|
assume rbx:nothing
|
|
ret
|
|
ENDMETHOD
|
|
|
|
METHOD socket_class, read, <VOIDARG>, <>, b:qword
|
|
local tmp:qword
|
|
|
|
mov rbx, thisPtr
|
|
assume rbx:ptr socket_class
|
|
mov rax, b
|
|
mov tmp, rax
|
|
invoke recv, [rbx].sock, tmp,MAX_READ_BYTES, 0
|
|
push rax
|
|
mov rax, tmp
|
|
mov b, rax
|
|
pop rax
|
|
invoke printf, CSTR("--> recv called, got %d bytes..",10), rax
|
|
assume rbx:nothing
|
|
ret
|
|
ENDMETHOD
|
|
|
|
METHOD socket_class, Destroy, <VOIDARG>, <>
|
|
mov rbx, thisPtr
|
|
assume rbx:ptr socket_class
|
|
invoke close, [rbx].sock
|
|
if @Platform eq windows64
|
|
invoke WSACleanup, addr [rbx].wsa
|
|
endif
|
|
.if [rbx].pai != 0
|
|
invoke freeaddrinfo, [rbx].pai
|
|
.endif
|
|
assume rbx:nothing
|
|
ret
|
|
ENDMETHOD
|
|
endif ;; __SOCKET_CLASS__
|
|
|
|
MAX_READ_BYTES equ 4023
|
|
|
|
.code
|
|
main proc
|
|
local lpSocket:ptr socket_class
|
|
local buffer:qword
|
|
|
|
mov lpSocket, _NEW(socket_class, CSTR("www.google.com"), CSTR("80"))
|
|
lpSocket->conn()
|
|
.if rax == -1
|
|
invoke exit, 0
|
|
ret
|
|
.endif
|
|
invoke printf, CSTR("-> Connected, sending data.",10)
|
|
lpSocket->write(CSTR("GET / HTTP 1.0",13,10,"Accept: text/html",13,10,13,10))
|
|
MEMALLOC(MAX_READ_BYTES)
|
|
mov buffer, rax
|
|
lpSocket->read(buffer)
|
|
invoke printf, CSTR("%s"), buffer
|
|
MEMFREE(buffer)
|
|
_DELETE(lpSocket)
|
|
invoke exit, 0
|
|
ret
|
|
main endp
|
|
|
|
end
|