-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathhttp-server.s
More file actions
239 lines (190 loc) · 4.17 KB
/
Copy pathhttp-server.s
File metadata and controls
239 lines (190 loc) · 4.17 KB
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
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
.intel_syntax noprefix
.equ AF_INET, 2
.equ SOCK_STREAM, 1
.equ IPPROTO_TCP, 0
.equ INADDR_ANY, 0
.equ PORT, 8080
.equ SOMAXCONN, 128
.equ BUFFER_SIZE, 1024
.equ O_RDONLY, 0
.equ O_WRONLY, 1
.equ O_CREAT, 64
# struct sockaddr_in
.equ SOCKADDR_IN_sin_family, 0
.equ SOCKADDR_IN_sin_port, 2
.equ SOCKADDR_IN_sin_addr, 6
.equ SOCKADDR_IN_size, 16
# struct in_addr
.equ IN_ADDR_s_addr, 0
.equ IN_ADDR_size, 4
.section .data
msg: .asciz "HTTP/1.0 200 OK\r\n\r\n"
.section .bss
.lcomm sockaddr_in, SOCKADDR_IN_size
.lcomm sockaddr_in_client, SOCKADDR_IN_size
.lcomm sockfd, 4
.lcomm sockfd_client, 4
.lcomm client_len, 4
.lcomm req_buffer, BUFFER_SIZE
.lcomm req_size, 4
.lcomm method, BUFFER_SIZE
.lcomm uri, BUFFER_SIZE
.lcomm body, 8
.lcomm content_length, 4
.lcomm file, BUFFER_SIZE
.section .text
.global _start
_start:
# Creating a socket (TCP)
mov edi, AF_INET
mov esi, SOCK_STREAM
mov edx, IPPROTO_TCP
mov rax, 41 # socket
syscall
mov dword ptr [sockfd], eax # saving the host socket
# Binding host socket to an address
mov ax, AF_INET
mov word ptr [sockaddr_in + SOCKADDR_IN_sin_family], ax # sockaddr_in.sin_family = AF_INET
mov ax, PORT
xchg al, ah # swap lower and high bytes
mov word ptr [sockaddr_in + SOCKADDR_IN_sin_port], ax # sockaddr_in.sin_port = 8080
mov eax, INADDR_ANY
bswap eax # Converting to network endianess (big endian)
mov dword ptr [sockaddr_in + SOCKADDR_IN_sin_addr + IN_ADDR_s_addr], eax # sockaddr_in.sin_addr.s_addr = '0.0.0.0'
mov rdi, sockfd
lea rsi, sockaddr_in # &addr
mov rdx, SOCKADDR_IN_size
mov rax, 49 # bind
syscall
# Making the host socket a passive socket
mov rdi, sockfd # host socket
mov rsi, SOMAXCONN # max connections
mov rax, 50 # listen
syscall
mov dword ptr [client_len], SOCKADDR_IN_size # client_len = SOCKADDR_IN_size
parent:
.accept:
mov rdi, sockfd # sockfd
lea rsi, sockaddr_in_client # addr
lea rdx, client_len # addrlen
mov rax, 43 # accept
syscall
mov dword ptr [sockfd_client], eax
.fork:
mov rax, 57 # fork
syscall
cmp rax, 0
je child
# close fd
mov rdi, sockfd_client
mov rax, 3
syscall
jmp .accept
child:
# close host socket
mov rdi, sockfd
mov rax, 3
syscall
# Reading client request
mov rdi, sockfd_client # fd
lea rsi, req_buffer # buf
mov rdx, BUFFER_SIZE # count
mov rax, 0 # read
syscall
mov dword ptr [req_size], eax
call get_method
mov rdi, rax
inc rdi
call get_uri
cmp rdi, 4
je .get
jmp .post
.get:
lea rdi, uri # path
mov rsi, O_RDONLY # flags
mov rax, 2 # open
syscall
mov rdi, rax
lea rsi, [file]
mov rdx, BUFFER_SIZE
mov rax, 0
syscall
mov rbx, rax
mov rdi, [sockfd_client] # fd
lea rsi, msg # buf
mov rdx, 19 # count
mov rax, 1 # write
syscall
mov rdi, [sockfd_client]
lea rsi, file
mov rdx, rbx
mov rax, 1
syscall
jmp exit
.post:
lea rdi, uri # path
mov rsi, O_WRONLY | O_CREAT # flags
mov rdx, 0644 # mode
mov rax, 2 # open
syscall
mov rdi, rax # fd
call get_body
mov rsi, [body] # buf
mov rdx, rax # count
mov rax, 1 # write
syscall
mov rax, 3
syscall
mov rdi, [sockfd_client] # fd
lea rsi, msg # buf
mov rdx, 19 # count
mov rax, 1 # write
syscall
jmp exit
exit:
mov rdi, sockfd_client
mov rax, 3
syscall
mov rdi, 0 # status
mov rax, 60 # exit
syscall
get_method:
xor rax, rax # index 0
.loop_get_method:
mov bl, byte ptr [req_buffer + rax]
cmp bl, 0x20 # checking the space char
je .done_get_method
mov byte ptr [method + rax], bl
inc rax
jmp .loop_get_method
.done_get_method:
ret
get_uri:
xor rax, rax # index 0
.loop_get_uri:
mov bl, byte ptr [req_buffer + rdi + rax]
cmp bl, 0x20 # checking if the value of the new addr is a space
je .done_uri
mov byte ptr [uri + rax], bl # copying the nth byte of req_buffer to uri
inc rax
jmp .loop_get_uri
.done_uri:
ret
get_body:
mov rax, req_size
dec rax
.find:
mov bl, byte ptr [req_buffer + rax]
cmp bl, 0x0a
jne .dec
.done_get_body:
inc rax
mov rbx, rax
lea rax, [req_buffer + rax]
mov [body], rax
mov rax, req_size
sub rax, rbx
ret
.dec:
dec rax
jmp .find