💾 Archived View for gmi.noulin.net › gitRepositories › spartserv › file › spartasm › main.asm.gmi captured on 2023-07-10 at 15:38:55. Gemini links have been rewritten to link to archived content
-=-=-=-=-=-=-
main.asm (6527B)
1 %include "constants.asm" 2 %include "macros.asm" 3 4 ;Follwing amd64 syscall standards for internal function calls: rdi rsi rdx r10 r8 r9 5 6 section .data 7 %include "data.asm" 8 9 section .bss 10 listen_socket: resq 1 11 listen_port: resw 1 12 one_constant: resq 1 13 directory_path: resq 1 14 15 section .text 16 %include "string.asm" 17 %include "syscall.asm" 18 19 global _start 20 21 _start: 22 23 mov QWORD [one_constant], 1 24 25 mov rdi, [rsp] ;Num of args 26 cmp rdi,3 ;Exit if no argument, should be directory location 27 jne exit_with_help 28 29 mov rdi, [rsp+16+8]; Port (second) parameter 30 call string_atoi 31 xchg al, ah 32 mov [listen_port], eax 33 34 mov rax, [rsp+16] ;Directory (first) parameter 35 mov [directory_path], rax 36 37 ;Try opening directory 38 mov rdi, [directory_path] 39 call sys_open_directory 40 41 cmp rax, 0 42 jl exit_with_no_directory_error 43 44 ;Create socket 45 call sys_create_tcp_socket 46 cmp rax, 0 47 jl exit_error 48 mov [listen_socket], rax 49 50 ;reuseaddr 51 mov rdi, [listen_socket] 52 call sys_reuse 53 54 ;Bind to port 55 call sys_bind_server 56 cmp rax, 0 57 jl exit_bind_error 58 59 ;Start listening 60 call sys_listen 61 62 mov rbp, rsp 63 sub rsp, 16 64 ;Offsets: 8 - socket fd, 16 - buffer 65 66 mov QWORD [rbp-16], 0 ; Used for pointer to recieve buffer 67 68 mov rdi, BUFFER_SIZE+2+URL_LENGTH_LIMIT+DIRECTORY_LENGTH_LIMIT ; Allow room to append nul, and to create path 69 call sys_mmap_mem 70 mov QWORD [rbp-16], rax 71 72 event_loop_start: 73 74 call sys_accept 75 76 mov [rbp-8], rax ; save fd 77 78 mov rdi, rax 79 call sys_cork ; cork it 80 81 ;Network stuff starts here 82 mov rdi, QWORD [rbp-8] ;fd 83 mov rsi, [rbp-16] ;buffer 84 mov rdx, BUFFER_SIZE ;size 85 call sys_recv 86 87 cmp rax, 0 88 jle close_client_connection 89 90 push rax ; save original received length 91 92 ; add nul 93 mov rdi, [rbp-16] 94 add rdi, rax 95 mov BYTE [rdi], 0x00 96 97 ;Make sure its a valid request 98 mov rdi, [rbp-16] 99 mov rsi, crlf 100 call string_ends_with 101 cmp rax, 1 102 jne invalid_request_response_pop_length 103 104 ;Find request 105 mov rax, 0x2F ; '/' character 106 mov rdi, [rbp-16] ;scan buffer 107 mov rcx, -1 ;Start count 108 cld ;Increment rdi 109 repne scasb 110 jne invalid_request_response_pop_length 111 mov rax, -2 112 sub rax, rcx ;Get the length 113 114 mov r8, rax ; start offset for requested file 115 mov rdi, [rbp-16] 116 add rdi, r8 117 mov rax, 0x20 ;'space' character 118 mov rcx, -1 119 cld 120 repne scasb 121 jne invalid_request_response_pop_length 122 mov rax, -1 123 sub rax, rcx 124 mov r9, rax 125 add r9, r8 ;end offset 126 127 ;TODO: Assuming it's a file, need directory handling too 128 129 pop r11 ; restore orig recvd length 130 mov rdi, [rbp-16] 131 add rdi, r11 ; end of buffer, lets use it! 132 mov r12, r11 ; keeping count 133 134 mov rsi, [directory_path] 135 xor r15, r15 ; Make sure directory path does not exceed DIRECTORY_LENGTH_LIMIT 136 137 append_directory_path: 138 inc r15 139 cmp r15, DIRECTORY_LENGTH_LIMIT 140 je invalid_request_response 141 lodsb 142 stosb 143 inc r12 144 cmp al, 0x00 145 jne append_directory_path 146 147 dec r12 ; get rid of 0x00 148 149 ; Adds the file to the end of buffer ( where we just put the document prefix ) 150 mov rsi, [rbp-16] 151 add rsi, r8 ; points to beginning of path 152 mov rdi, [rbp-16] 153 add rdi, r12 ;go to end of buffer 154 mov rcx, r9 155 sub rcx, r8 156 cmp rcx, URL_LENGTH_LIMIT ; Make sure this does not exceed URL_PATH_LENGTH 157 jg invalid_request_response 158 add r12, rcx 159 rep movsb 160 161 dec r12 ; exclude space character 162 mov rdi, [rbp-16] 163 add rdi, r12 164 mov BYTE [rdi], 0x00 ; add nul 165 166 mov r9, r11 ; saving offset into a stack saved register 167 ; [rbp-16] + r9 now holds string for file opening 168 169 remove_pre_dir: 170 171 ;-----Simple request logging 172 ; mov rdi, msg_request_log 173 ; mov rsi, msg_request_log_len 174 ; call sys_write 175 ; mov rdi, [rbp-16] 176 ; add rdi, r9 177 ; call get_string_length 178 ; mov rsi, rax 179 ; call print_line 180 ;-----End Simple logging 181 182 mov rdi, [rbp-16] 183 add rdi, r9 184 mov rsi, filter_prev_dir ; remove any '../' 185 call string_remove 186 cmp rax, 0 187 jne remove_pre_dir 188 189 190 ; TODO content types 191 ; mov rdi, [rbp-16] 192 ; add rdi, r9 193 ; call detect_content_type 194 ; mov r8, rax ;r8: Content Type 195 196 ;------------response---------------- 197 198 ;Try to open requested file 199 mov rdi, [rbp-16] 200 add rdi, r9 201 call sys_open 202 cmp rax, 0 203 204 jl invalid_request_response ;file not found 205 206 ; Done with buffer offsets, put response and data into it starting at beg 207 mov r10, rax ; r10: file fd 208 209 ; we're good to go 210 211 ;---------2 Response Start------------ 212 213 ; get file size 214 mov rdi, r10 ; fd 215 xor rsi, rsi 216 mov rdx, LSEEK_END 217 call sys_lseek 218 219 ;rax - total filesize 220 push rax 221 222 ;Seek to beg of file 223 mov rdi, r10 ; fd 224 xor rsi, rsi 225 mov rdx, LSEEK_SET 226 call sys_lseek 227 228 ; send response header 229 mov rdi, [rbp-8] ; socket 230 mov rsi, text_gemini_s 231 mov rdx, text_gemini_s_len 232 call sys_send 233 234 cmp rax, 0 235 jle close_file 236 237 ; send file 238 mov rdi, [rbp-8] ; socket 239 mov rsi, r10 ; fd 240 pop rdx ; file size 241 call sys_sendfile 242 jmp close_file 243 ;---------2 Response End-------------- 244 245 ;---------4 Response Start------------ 246 invalid_request_response_pop_length: 247 pop rsi 248 249 invalid_request_response: 250 mov rdi, [rbp-8] ; socket 251 mov rsi, invalid_s 252 mov rdx, invalid_s_len 253 call sys_send 254 255 jmp close_client_connection 256 ;---------4 Response End-------------- 257 258 close_file: 259 ;Uncork 260 mov rdi, [rbp-8] 261 call sys_uncork 262 263 ;Close File 264 mov rdi, r10 265 call sys_close 266 267 ;Close Socket 268 close_client_connection: 269 mov rdi, [rbp-8] 270 call sys_close 271 272 jmp event_loop_start 273 274 exit_with_no_directory_error: 275 mov rdi, msg_not_a_directory 276 mov rsi, msg_not_a_directory_len 277 call print_line 278 jmp exit 279 280 exit_with_help: 281 mov rdi, msg_help 282 mov rsi, msg_help_len 283 call print_line 284 jmp exit 285 286 exit_error: 287 mov rdi, msg_error 288 mov rsi, msg_error_len 289 call print_line 290 291 mov rdi, -1 292 mov rax, SYS_EXIT_GROUP 293 syscall 294 jmp exit 295 296 exit_bind_error: 297 mov rdi, msg_bind_error 298 mov rsi, msg_bind_error_len 299 call print_line 300 301 mov rdi, -1 302 mov rax, SYS_EXIT_GROUP 303 syscall 304 jmp exit 305 306 exit: 307 308 mov rdi, [listen_socket] 309 call sys_close 310 311 xor rdi, rdi 312 mov rax, SYS_EXIT_GROUP 313 syscall 314