commit 3c08cc1c21e6644bb73255fe032d74ca13d1f4eb Author: Tomek Dubrownik Date: Sun Dec 15 21:35:41 2013 +0100 initial - an echo server for now (prints back the first 2kB of the request as text/plain) diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..0e51fa0 --- /dev/null +++ b/Makefile @@ -0,0 +1,8 @@ +asmttp: asmttp.o + ld asmttp.o -o asmttp +asmttp.o: asmttp.asm definitions.inc + nasm -f elf64 -o asmttp.o asmttp.asm +definitions.inc: define.e + ./define.e > definitions.inc +define.e: define.c + gcc -o define.e define.c diff --git a/asmttp.asm b/asmttp.asm new file mode 100644 index 0000000..bc58321 --- /dev/null +++ b/asmttp.asm @@ -0,0 +1,209 @@ +[BITS 64] +%include "definitions.inc" +%define sysread 0 +%define syswrite 1 +%define sysclose 3 +%define sysmmap 9 +%define sysmunmap 11 +%define sysrtsigaction 13 +%define syssocket 41 +%define sysaccept 43 +%define sysbind 49 +%define syslisten 50 +%define syssetsockopt 54 +%define sysclone 56 +%define sysexit 60 + +%define backlog 100 +%define childsize 2048 + +global _start +section .data + +reuse: dd 1 +reuselen: equ $ - reuse + +sockaddr: + sin_family dw AF_INET + sin_port db 1fh, 40h ; 8000 + sin_addr db 0, 0, 0, 0 + addrlen equ 16 + +status: db "HTTP/1.0 200 OK",13,10 + db "Content-Type: text/plain",13,10 + db 13,10 + + + ;; db "GIF89a" + ;; dw 8 ; width (LE) + ;; dw 8 ; heigh + ;; db 10000000b ; + ;; db 0 ; bg color + ;; db 0 ; pixel aspect + ;; ;; global color table + ;; db 0,0,0 + ;; db 0xff, 0xff, 0xff + ;; ;; image descriptor + ;; db 0x2c ; image separator + ;; dw 0 ; image left + ;; dw 0 ; image top + ;; dw 8 ; width + ;; dw 8 ; height + ;; db 0 ; packed + ;; ;; table + ;; db 13 + ;; db 4 + + ;; db 1 + ;; db 10110000b + ;; db 00101010b + ;; db 10000000b + ;; db 0 + + +status_len: equ $ - status + +pipeign: + handler dd SIG_IGN + mask dd 0 + +section .bss +clientaddr: + cl_family resw 1 + cl_port resw 1 + cl_addr resd 1 + pad resq 1 +cl_addrlen resd 1 + +section .text +_start: + mov rax, sysrtsigaction + mov rdi, SIGPIPE + mov rsi, pipeign + mov rdx, 0 + mov r10, 8 + syscall + + mov rax, syssocket + mov rdi, AF_INET + mov rsi, SOCK_STREAM + xor rdx, rdx + syscall + test rax, rax + js fail + mov rdi, rax + + mov rax, syssetsockopt + mov rsi, SOL_SOCKET + mov rdx, SO_REUSEADDR + mov r10, reuse + mov r8, reuselen + syscall + test rax, rax + jnz fail + + mov rax, sysbind + mov rsi, sockaddr + mov rdx, addrlen + syscall + test rax, rax + jnz fail + + mov rax, syslisten + mov rsi, 10 + syscall + test rax, rax + jnz fail + + mov r12, rdi + + xor rsp, rsp +accept: + mov rax, sysaccept + mov rsi, clientaddr + mov rdx, cl_addrlen + syscall + test rax, rax + js fail + mov rsi, rax + +clone: + mov rax, sysclone + mov rdi, 0x00013fff + xor rdx, rdx + syscall + + test rax, rax + js fail + + test rsp, rsp + jnz child + + mov rdi, r12 + + jmp accept +fail: + mov rdi, rax + jmp exit +success: + mov rdi, 0 +exit: + mov rax, sysexit + syscall + +child: + mov r12, rsp + + mov rax, sysmmap + mov rdi, 0 + mov rsi, childsize + mov rdx, PROT_WRITE + mov r10, MAP_ANONYMOUS + or r10, MAP_PRIVATE + mov r8, 0 + mov r9, 0 + syscall + + test rax, MAP_FAILED + je fail + + mov rsp, rax + mov rdi, r12 + +read2k: + mov rax, sysread + mov rsi, rsp + mov rdx, childsize + syscall + test rax, rax + js close + + mov r12, rax +write_head: + mov rax, syswrite + mov rsi, status + mov rdx, status_len + syscall + + cmp rax, 0 + jl close + +write_echo: + mov rax, syswrite + mov rsi, rsp + mov rdx, r12 + syscall + + jmp close +write: + mov rax, syswrite + +close: + mov rax, sysclose + syscall + mov rax, sysmunmap + mov rdi, rsp + mov rsi, childsize + syscall + + jmp success diff --git a/define.c b/define.c new file mode 100644 index 0000000..435a3d9 --- /dev/null +++ b/define.c @@ -0,0 +1,18 @@ +#include +#include +#include +#include +#define DEFINE(sym) printf("%%define %s %d\n", #sym, sym) +int main() { + DEFINE(SOCK_STREAM); + DEFINE(AF_INET); + DEFINE(SOL_SOCKET); + DEFINE(SO_REUSEADDR); + DEFINE(SIGPIPE); + DEFINE(SIG_IGN); + DEFINE(MAP_ANONYMOUS); + DEFINE(MAP_FAILED); + DEFINE(MAP_PRIVATE); + DEFINE(PROT_WRITE); + return 0; +} diff --git a/offset.c b/offset.c new file mode 100644 index 0000000..730354e --- /dev/null +++ b/offset.c @@ -0,0 +1,16 @@ +#include +#include +#include +#define OFFSET(type, attr) printf("%s %d\n", #attr, &(((type*) 0)->attr)) + +int main() { + OFFSET(struct sockaddr_in, sin_family); + OFFSET(struct sockaddr_in, sin_port); + OFFSET(struct sockaddr_in, sin_addr); + printf("%d\n", sizeof(struct sockaddr_in)); + + OFFSET(struct sigaction, sa_handler); + OFFSET(struct sigaction, sa_mask); + OFFSET(struct sigaction, sa_flags); + OFFSET(struct sigaction, sa_restorer); +}