Questo sito utilizza cookies solo per scopi di autenticazione sul sito e nient'altro. Nessuna informazione personale viene tracciata. Leggi l'informativa sui cookies.
Username: Password: oppure
Simple Server - sserv.asm

sserv.asm

Caricato da: ZioCrocifisso
Scarica il programma completo

  1. section .data
  2.         server_addr:                                    ;Indirizzo del server
  3.                 dw 2                                    ;P/AF_INET (Famiglia dell'indirizzo)
  4.                 server_port dw 0x901f                   ;Porta (in big endian)
  5.                 server_in_addr dd 0                     ;Indirizzo IP (0.0.0.0, ovvero qualunque)
  6.                 dq 0                                    ;Padding (sin_zero)
  7.  
  8.         addr_len equ 16                                 ;Dimensione della struttura dell'indirizzo
  9.  
  10.         sleep_timespec:                                 ;Tempo di attesa
  11.                 dq 0                                    ;Secondi
  12.                 dq 500000000                            ;Nanosecondi
  13.  
  14.         bufmax equ 128
  15.         buffer: times bufmax db 0                       ;Buffer che conterrà i dati ricevuti
  16.  
  17.         se_str db `HTTP/1.1 500 Internal Server Error\r\n\r\nInternal Server Error.\r\n`
  18.         se_len equ $ - se_str
  19.  
  20.         br_str db `HTTP/1.1 400 Bad Request\r\n\r\nBad Request.\r\n`
  21.         br_len equ $ - se_len
  22.  
  23.         nf_str db `HTTP/1.1 404 Not Found\r\n\r\nNot Found.\r\n`
  24.         nf_len equ $ - nf_str
  25.  
  26.         ok1_str db `HTTP/1.1 200 OK\r\nContent-length: `
  27.         ok1_len equ $ - ok1_str
  28.         ok2_str db `\r\nConnection: close\r\n\r\n`
  29.         ok2_len equ $ - ok2_str
  30.  
  31.         true dd 1
  32.         index_str db 'index.html', 0
  33.         index_len equ $ - index_str
  34.  
  35.         numbuf times 20 db ' '                          ;Buffer in cui contenere i numeri
  36.  
  37.  
  38. section .text
  39. _start:
  40.         ;Creazione del socket
  41.         mov rax, 41                                     ;Codice della syscall socket()
  42.         mov rdi, 2                                      ;P/AF_INET (Famiglia del protocollo)
  43.         mov rsi, 1                                      ;SOCK_STREAM (Tipo di protocollo)
  44.         mov rdx, 0                                      ;Protocollo (non necessario, viene scelto automaticamente)
  45.         syscall                                         ;Invoca la syscall
  46.         cmp rax, -1                                     ;Controlla se ci sono stati errori
  47.         jle error
  48.         mov r12, rax                                    ;Copia il risultato (id del socket) nel registro 12
  49.  
  50.         ;Imposta l'opzione di riutilizzo dell'indirizzo
  51.         mov rax, 54                                     ;Syscall setsockopt()
  52.         mov rdi, r12
  53.         mov rsi, 1                                      ;SOL_SOCKET (livello di setsockopt)
  54.         mov rdx, 2                                      ;SO_REUSEADDR (riutilizzare l'indirizzo)
  55.         mov r10, true                                   ;Puntatore al valore dell'opzione
  56.         mov r8, 4                                       ;Dimensione del valore
  57.         syscall
  58.  
  59.         ;Impostazione dell'indirizzo di ascolto
  60.         mov rax, 49                                     ;Syscall bind()
  61.         mov rdi, r12                                    ;File descriptor del socket
  62.         mov rsi, server_addr                            ;Puntatore a indirizzo del server
  63.         mov rdx, addr_len                               ;Dimensione dell'indirizzo
  64.         syscall
  65.         cmp rax, 0
  66.         jne error
  67.  
  68.         ;Ascolto per le connessioni
  69.         mov rax, 50                                     ;Syscall listen()
  70.         mov rdi, r12
  71.         mov rsi, 10                                     ;Backlog (limite di connessioni in coda)
  72.         syscall
  73.         cmp rax, -1
  74.         jle error
  75.  
  76.         .clientloop:
  77.                 ;Connessione ai client
  78.                 mov rax, 43                             ;Syscall accept()
  79.                 mov rdi, r12
  80.                 mov rsi, 0                              ;Puntatore all'indirizzo del client (0 per ignorarlo)
  81.                 mov rdx, 0                              ;Puntatore alla dimensione dell'indirizzo
  82.                 syscall
  83.                 cmp rax, -1
  84.                 jle error
  85.                 mov r13, rax                            ;File descriptor del socket per il client
  86.  
  87.                 ;Ricezione dei dati
  88.                 mov rax, 45                             ;Syscall recvfrom()
  89.                 mov rdi, r13
  90.                 mov rsi, buffer                         ;Puntatore al buffer che conterrà i dati ricevuti
  91.                 mov rdx, (bufmax - 1)                   ;Dimensione del buffer
  92.                 mov r10, 0
  93.                 mov r8, 0
  94.                 mov r9, 0
  95.                 syscall
  96.                 cmp rax, -1
  97.                 jle .servererror
  98.                 mov r15, rax
  99.  
  100.                 mov rcx, 0
  101.                 .searchloop:                            ;Cerca il carattere '/' indicante l'inizio del percorso
  102.                         cmp [buffer + rcx], byte '/'
  103.                         je .sendfile
  104.                         inc rcx
  105.                         cmp rcx, r15                    ;Se finisce il buffer e non trova il percorso
  106.                         jge .badrequest                 ;Spedisce un errore 400 (bad request)
  107.                         jmp .searchloop
  108.  
  109.                 .servererror:
  110.                         mov r14, se_str                 ;Sceglie la stringa per l'errore 500
  111.                         mov r15, se_len                 ;Imposta la sua lunghezza
  112.                         call send
  113.                         jmp .close
  114.  
  115.                 .badrequest:
  116.                         mov r14, br_str                 ;Sceglie la stringa per l'errore 400
  117.                         mov r15, br_len                 ;Dimensione
  118.                         call send
  119.                         jmp .close
  120.  
  121.                 .notfound:
  122.                         mov r14, nf_str                 ;Sceglie la stringa per l'errore 404
  123.                         mov r15, nf_len                 ;Dimensione
  124.                         call send
  125.                         jmp .close
  126.  
  127.                 .sendfile:
  128.                         inc rcx
  129.                         lea rbx, [buffer + rcx]
  130.                         sub r15, rcx
  131.                         mov rcx, 0
  132.                         .endloop:                       ;Cerca lo spazio che indica la fine del percorso
  133.                                 cmp [rbx + rcx], byte ' '
  134.                                 je .verifypath
  135.                                 inc rcx
  136.                                 cmp rcx, r15
  137.                                 jge .badrequest
  138.                                 jmp .endloop
  139.  
  140.                         .verifypath:
  141.                                 mov [rbx + rcx], byte 0
  142.                                 cmp rcx, 0
  143.                                 jne .openfile
  144.                                 mov rbx, index_str
  145.                                 mov rcx, index_len
  146.  
  147.                         .openfile:
  148.                                 mov rax, 2              ;Syscall open()
  149.                                 mov rdi, rbx            ;Percorso
  150.                                 mov rsi, 0              ;O_RDONLY (sola lettura)
  151.                                 mov rdx, 0              ;(in questo caso non serve)
  152.                                 syscall
  153.                                 cmp rax, -1
  154.                                 jle .notfound
  155.                                 mov rbx, rax            ;Salva l'fd in un registro appartenente al chiamante
  156.  
  157.                         ;Invia la prima parte degli header
  158.                         mov r14, ok1_str
  159.                         mov r15, ok1_len
  160.                         call send
  161.  
  162.                         ;Ottiene la dimensione del file
  163.                         mov rdi, rbx
  164.                         call filesize
  165.  
  166.                         ;La converte in una stringa
  167.                         mov rdi, rax                    ;Numero da inviare
  168.                         mov rsi, numbuf                 ;Buffer in cui verrà contenuto il numero
  169.                         call itoa
  170.  
  171.                         ;La invia
  172.                         mov r14, numbuf                 ;Stringa contentente il numero
  173.                         mov r15, rax                    ;Sua dimensione
  174.                         call send
  175.  
  176.                         ;Invia il resto degli header
  177.                         mov r14, ok2_str
  178.                         mov r15, ok2_len
  179.                         call send
  180.  
  181.                         ;Legge e invia bufmax byte alla volta
  182.                         .sendloop:
  183.                                 mov rax, 0              ;Syscall read()
  184.                                 mov rdi, rbx            ;File descriptor del file aperto
  185.                                 mov rsi, buffer         ;Puntatore al buffer
  186.                                 mov rdx, bufmax         ;Dimensione massima del buffer
  187.                                 syscall
  188.                                 cmp rax, 0
  189.                                 jle .close
  190.  
  191.                                 mov r14, buffer
  192.                                 mov r15, rax
  193.                                 call send
  194.  
  195.                                 jmp .sendloop
  196.                                
  197.  
  198.                 .close:
  199.                 ;Chiude il file
  200.                 mov rax, 3                              ;Syscall close()
  201.                 mov rdi, rbx
  202.                 syscall
  203.  
  204.                 ;Comunica che il socket verrà chiuso
  205.                 mov rax, 48                             ;Syscall shutdown()
  206.                 mov rdi, r13
  207.                 mov rsi, 0
  208.                 syscall
  209.  
  210.                 ;Attende per un po'
  211.                 mov rax, 35                             ;Syscall nanosleep()
  212.                 mov rdi, sleep_timespec
  213.                 mov rsi, 0
  214.                 syscall
  215.  
  216.                 ;Chiude il socket del client
  217.                 mov rax, 3                              ;Syscall close()
  218.                 mov rdi, r13
  219.                 syscall
  220.  
  221.                 jmp .clientloop
  222.  
  223. send:
  224.         ;Invio dei dati
  225.         mov rax, 44                                     ;Syscall sendto()
  226.         mov rdi, r13                                    ;File descriptor del client
  227.         mov rsi, r14                                    ;Puntatore ai dati da inviare
  228.         mov rdx, r15                                    ;Dimensione dei dati da inviare
  229.         mov r10, 0x8000                                 ;Flags
  230.         mov r8, 0                                       ;Puntatore all'indirizzo (ignorato)
  231.         mov r9, 0                                       ;Dimensione dell'indirizzo (ignorata)
  232.         syscall
  233.         ret
  234.  
  235. error:
  236.         neg rax
  237.         mov rdi, rax                                    ;Codice dell'errore
  238.         mov rax, 60                                     ;Syscall exit()
  239.         syscall
  240.         ret
  241.  
  242. filesize:
  243.         ;Si sposta verso la fine e ottiene la posizione
  244.         mov rax, 8                                      ;Syscall lseek()
  245.         ;mov rdi, rdi                                   ;Il primo argomento è già il file
  246.         mov rsi, 0                                      ;Offset 0
  247.         mov rdx, 2                                      ;SEEK_END (dalla fine del file)
  248.         syscall
  249.         mov r10, rax                                    ;Salva l'indirizzo
  250.  
  251.         ;Torna all'inizio del file
  252.         mov rax, 8
  253.         ;mov rdi, rdi
  254.         mov rsi, 0
  255.         mov rdx, 0                                      ;SEEK_SET
  256.         syscall
  257.  
  258.         mov rax, r10                                    ;Risultato
  259.         ret
  260.  
  261. itoa:
  262.         mov rax, rdi
  263.         mov rcx, 1                                      ;Numero di cifre
  264.         mov r15, 10
  265.  
  266.         .divloop:
  267.                 xor rdx, rdx
  268.                 div r15
  269.                 add dl, '0'                             ;Trasforma il resto della divisione in un carattere ASCII
  270.                 mov rdi, 20
  271.                 sub rdi, rcx                            ;Calcola la posizione dalla fine
  272.                 mov byte [rdi + rsi], dl                ;Copia il resto della divisione nel buffer
  273.  
  274.                 cmp rcx, 20
  275.                 jge .return
  276.                 inc rcx
  277.                 jmp .divloop
  278.  
  279.         .return:
  280.                 mov rax, 20                             ;TODO: spostare
  281.                 ret