Skip to content

Instantly share code, notes, and snippets.

@ucotta
Forked from DGivney/socket.asm
Created March 19, 2021 19:00
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save ucotta/d51985e485ccbd782dfdb4b94bf1886d to your computer and use it in GitHub Desktop.
Save ucotta/d51985e485ccbd782dfdb4b94bf1886d to your computer and use it in GitHub Desktop.
NASM socket programming example
; Socket
; Compile with: nasm -f elf socket.asm
; Link with (64 bit systems require elf_i386 option): ld -m elf_i386 socket.o -o socket
; Run with: ./socket
%include 'functions.asm'
SECTION .data
; our response string
response db 'HTTP/1.1 200 OK', 0Dh, 0Ah, 'Content-Type: text/html', 0Dh, 0Ah, 'Content-Length: 14', 0Dh, 0Ah, 0Dh, 0Ah, 'Hello World!', 0Dh, 0Ah, 0h
SECTION .bss
buffer resb 255, ; variable to store request headers
SECTION .text
global _start
_start:
xor eax, eax ; init eax 0
xor ebx, ebx ; init ebx 0
xor edi, edi ; init edi 0
xor esi, esi ; init esi 0
_socket:
push byte 6 ; push 6 onto the stack (IPPROTO_TCP)
push byte 1 ; push 1 onto the stack (SOCK_STREAM)
push byte 2 ; push 2 onto the stack (PF_INET)
mov ecx, esp ; move address of arguments into ecx
mov ebx, 1 ; invoke subroutine SOCKET (1)
mov eax, 102 ; invoke SYS_SOCKETCALL (kernel opcode 102)
int 80h ; call the kernel
_bind:
mov edi, eax ; move return value of SYS_SOCKETCALL into edi (file descriptor for new socket, or -1 on error)
push dword 0x00000000 ; move 0 dec onto the stack IP ADDRESS
push word 0x2923 ; move 9001 dec onto stack PORT
push word 2 ; move 2 dec onto stack AF_INET
mov ecx, esp ; move address of stack pointer into ecx
push byte 16 ; move 16 dec onto stack (arguments length)
push ecx ; push the address of arguments onto stack
push edi ; push the file descriptor onto stack
mov ecx, esp ; move address of arguments into ecx
mov ebx, 2 ; invoke subroutine BIND (2)
mov eax, 102 ; invoke SYS_SOCKETCALL (kernel opcode 102)
int 80h ; call the kernel
_listen:
push byte 1 ; move 1 onto stack (max queue length argument)
push edi ; push the file descriptor onto stack
mov ecx, esp ; move address of arguments into ecx
mov ebx, 4 ; invoke subroutine LISTEN (4)
mov eax, 102 ; invoke SYS_SOCKETCALL (kernel opcode 102)
int 80h ; call the kernel
_accept:
push byte 0 ; push 0 dec onto stack (address length argument)
push byte 0 ; push 0 dec onto stack (address argument)
push edi ; push the file descriptor onto stack
mov ecx, esp ; move address of arguments into ecx
mov ebx, 5 ; invoke subroutine ACCEPT (5)
mov eax, 102 ; invoke SYS_SOCKETCALL (kernel opcode 102)
int 80h ; call the kernel
_fork:
mov esi, eax ; move return value of SYS_SOCKETCALL into esi (file descriptor for accepted socket, or -1 on error)
mov eax, 2 ; invoke SYS_FORK (kernel opcode 2)
int 80h ; call the kernel
cmp eax, 0 ; if return value of SYS_FORK in eax is zero we are in the child process
jz _read ; jmp in child process to _read
jmp _accept ; jmp in parent process to _accept
_read:
mov edx, 255 ; number of bytes to read (we will only read the first 255 bytes for simplicity)
mov ecx, buffer ; move the memory address of our buffer variable into ecx
mov ebx, esi ; move esi into ebx (accepted socket file descriptor)
mov eax, 3 ; invoke SYS_READ (kernel opcode 3)
int 80h ; call the kernel
mov eax, buffer ; move the memory address of our buffer variable into eax for printing
call sprintLF ; call our string printing function
_write:
mov edx, 78 ; move 78 dec into edx (length in bytes to write)
mov ecx, response ; move address of our response variable into ecx
mov ebx, esi ; move file descriptor into ebx (accepted socket id)
mov eax, 4 ; invoke SYS_WRITE (kernel opcode 4)
int 80h ; call the kernel
_close:
mov ebx, esi ; move esi into ebx (accepted socket file descriptor)
mov eax, 6 ; invoke SYS_CLOSE (kernel opcode 6)
int 80h ; call the kernel
_exit:
call quit ; call our quit function
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment