-
Notifications
You must be signed in to change notification settings - Fork 4
/
server.asm
169 lines (149 loc) · 8.21 KB
/
server.asm
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
; HTTP Assembly Server
;
; Run:
; $ make build && ./server
; OR
; $ ./Run-NASM.sh server.asm
;
; Listening on http://127.0.0.1:3926
SECTION .data
socket dq 0
socketOn dw 1
client dq 0
fileName db "index.html", 0h
filePtr dq 0
reqLen dw 0
buffLen equ 512
reqBuff TIMES buffLen db 0
resBuff TIMES buffLen db 0
startMsg:
db "Listening on Port 3926 ...", 0ah,0ah,0h
startMsgLen equ $ - startMsg
http200:
db "HTTP/1.1 200 OK", 0ah
db "Date: xxx, xx xxx xxxx xx:xx:xx xxx", 0ah
db "Server: HTTP-ASM64", 0ah
db "Content-Type: text/html", 0ah,0ah,0h
http200Len equ $ - http200
http404:
db "HTTP/1.1 404 Not Found", 0ah
db "Date: xxx, xx xxx xxxx xx:xx:xx xxx", 0ah
db "Server: HTTP-ASM64", 0ah
db "Content-Type: text/html", 0ah,0ah,0
http404Len equ $ - http404
SECTION .bss
socketAddr resq 2
SECTION .text
global _start
_start: ; -------------[Make Socket]-----------
mov rax,41 ; sys_socket() Create Socket
mov rdi,2 ; Set Address Family
mov rsi,1 ; Set socket byte stream
mov rdx,6 ; Set TCP Socket Protocol
syscall ; Return socket rax
mov [socket],rax ; Store socket pointer
; -------------[Socket Address]--------
push rbp ; Store stack pointer (base)
mov rbp,rsp ; Move stack top to base
push dword 0 ; Set 4-byte address padding
push dword 0x0100007F ; 127.0.0.1 UINT32 Big Endian(ABCD)
push word 0x560f ; Port 3926 UINT16 Little Endian(BA)
push word 2 ; Set Address Family
mov [socketAddr],rsp ; Store address pointer
add rsp,12 ; Clean up stack
pop rbp ; Restore original stack pointer
; -------------[Reuse Address]---------
mov rax,54 ; sys_setsockopt() Set socket options
mov rdi,[socket] ; Load socket pointer
mov rsi,1 ; Socket byte stream
mov rdx,2 ; Enable address reuse
mov r10,socketOn ; Set socket enabled
mov r8,dword 32 ; Load 32 bit socket address size
syscall ; Return socket rdi
cmp rax,0 ; Check for error
jne closeServer ; Close server if error
; -------------[Bind Socket]-----------
mov rax,49 ; sys_bind()
mov rdi,[socket] ; Load socket pointer
mov rsi,[socketAddr] ; Load address pointer
mov rdx,dword 32 ; Load 32 bit socket address size
syscall ;
cmp rax,0 ; Check for error
jne closeServer ; Close server if error
; -------------[Listen]----------------
mov rax,1 ; sys_write()
mov rdi,1 ; Set to STDOUT
mov rsi,startMsg ; Load start message
mov rdx,startMsgLen ; Load start message length
syscall
mov rax,50 ; sys_listen()
mov rdi,[socket] ; Load socket pointer
mov rsi,8 ; Load max clients
syscall ;
serverAccept: ; ---------[Accept Connection]---------
mov rax,43 ; sys_accept(socket,0,0)
mov rdi,[socket] ; Load socket pointer
mov rsi,dword 0 ; xor rsi,rsi
mov rdx,dword 0 ; xor rdx,rdx
syscall ; Returns socket file descriptor
cmp rax,0 ; File descriptor is non-negative
jle closeServer ; Close if bad file descriptor
mov [client],rax ; Store file descriptor pointer
; -------[Process Client Request]------
mov rax,0 ; sys_read()
mov rdi,[client] ; Load client pointer (FD)
mov rsi,reqBuff ; Load request buffer
mov rdx,buffLen ; Load buffer length
syscall ; Return bytes read rax
mov [reqLen],rax ; Store bytes read for request
; -------------[Log Headers]-----------
mov rax,1 ; sys_write()
mov rdi,1 ; Set to STDOUT
mov rsi,reqBuff ; Load request buffer
mov rdx,[reqLen] ; Load request buffer length
syscall ;
; ----------[Read Index.html]----------
mov rax,2 ; sys_open()
mov rdi,fileName ; Set file name to open
mov rsi,0 ; Set file read only
syscall ; Return new file descriptor rax
cmp rax,0 ; Check if error - 404 Error
jle closeClient ; Close client if error
mov [filePtr],rax ; Store file descriptor pointer
mov rcx,qword 0 ; Initialize counter
sendHeaders: ; -----------[Send Headers]------------
mov rax,1 ; sys_write()
mov rdi,[client] ; Load client pointer
mov rsi,http200 ; Load HTTP 200 Message
mov rdx,http200Len ; Load HTTP 200 Message Length
syscall ;
readHTML: ; ---------[HTML Output Loop]----------
mov rax,0 ; sys_read()
mov rdi,[filePtr] ; Load file pointer
mov rsi,resBuff ; Load response buffer
mov rdx,buffLen ; Load buffer length
syscall ; Return bytes read rax
cmp rax,1 ; Check error or EOF
jl closeClient ; Close client if error or done read
mov rcx,rax ; Store bytes read to counter
mov rax,1 ; -------------[Output HTML]-----------
mov rdi,[client] ; Load client pointer
mov rsi,resBuff ; Load response buffer
mov rdx,rcx ; Load counter
syscall ;
jmp readHTML ; Loop Read and Write
closeClient: ; ------[Close Client Connection]------
mov rax,3 ; sys_close()
mov rdi,[client] ; Load client pointer
syscall ;
jmp serverAccept ; Loop to another client
closeServer: ; --------[Close Server Socket]--------
mov rax,3 ; sys_close()
mov rdi,[socket] ; Load socket pointer
syscall ;
xor rax,rax ; Set rax 0 for successful close
_exit: ; -------------[Program End]-----------
pop rbp ; Restore stack pointer
mov rdi,rax ; Load 0
mov rax,60 ; exit() Exit 0
syscall ;