1
+ section .data
2
+ response db 'HTTP/1.1 200 OK' , 0Dh , 0Ah , 'Content-Type: text/html' , 0Dh , 0Ah , 'Content-Length: 16' , 0Dh , 0Ah , 0Dh , 0Ah , 'ABCDABCDABCDABCD' , 0Dh , 0Ah , 0h
3
+ prompt db 'Running on localhost at port: '
4
+ section .bss
5
+ buffer resb 255 , ; variable to store request headers
6
+ socket resw 0 ; variable to store the socket number in hex, reverse bytes
7
+
8
+ section .text
9
+ InitialiseServer:
10
+ xor eax , eax
11
+ xor ebx , ebx
12
+ xor edi , edi
13
+ xor esi , esi
14
+ ;Initiliase the socket
15
+ push BYTE 6 ; push 6 onto the stack (IPPROTO_TCP)
16
+ push BYTE 1 ; push 1 onto the stack (SOCK_STREAM)
17
+ push BYTE 2 ; push 2 onto the stack (PF_INET)
18
+ mov ecx , esp ; move address of arguments into ecx
19
+ mov ebx , 1 ; invoke subroutine SOCKET (1)
20
+ mov eax , 102 ; invoke SYS_SOCKETCALL (kernel opcode 102)
21
+ int 80h ; call the kernel
22
+
23
+ ;Bing the the server to the socket at localhost
24
+ mov edi , eax ; move return value of SYS_SOCKETCALL into edi (file descriptor for new socket, or -1 on error)
25
+ push DWORD 0x00000000 ; move 0 dec onto the stack IP ADDRESS
26
+ push WORD [ socket ] ; move 9001 dec onto stack PORT
27
+ push WORD 2 ; move 2 dec onto stack AF_INET
28
+ mov ecx , esp ; move address of stack pointer into ecx
29
+ push BYTE 16 ; move 16 dec onto stack (arguments length)
30
+ push ecx ; push the address of arguments onto stack
31
+ push edi ; push the file descriptor onto stack
32
+ mov ecx , esp ; move address of arguments into ecx
33
+ mov ebx , 2 ; invoke subroutine BIND (2)
34
+ mov eax , 102 ; invoke SYS_SOCKETCALL (kernel opcode 102)
35
+ int 80h ; call the kernel
36
+
37
+ ;Listen on the port for an encoming request
38
+ push BYTE 1 ; move 1 onto stack (max queue length argument)
39
+ push edi ; push the file descriptor onto stack
40
+ mov ecx , esp ; move address of arguments into ecx
41
+ mov ebx , 4 ; invoke subroutine LISTEN (4)
42
+ mov eax , 102 ; invoke SYS_SOCKETCALL (kernel opcode 102)
43
+ int 80h ; call the kernel
44
+
45
+ ;Accept an incoming request
46
+ .accept:
47
+ push BYTE 0 ; push 0 dec onto stack (address length argument)
48
+ push BYTE 0 ; push 0 dec onto stack (address argument)
49
+ push edi ; push the file descriptor onto stack
50
+ mov ecx , esp ; move address of arguments into ecx
51
+ mov ebx , 5 ; invoke subroutine ACCEPT (5)
52
+ mov eax , 102 ; invoke SYS_SOCKETCALL (kernel opcode 102)
53
+ int 80h ; call the kernel
54
+
55
+ ;Fork the server into 2 child processes, one to read the buffer, one to accept the request
56
+ mov esi , eax ; move return value of SYS_SOCKETCALL into esi (file descriptor for accepted socket, or -1 on error)
57
+ mov eax , 2 ; invoke SYS_FORK (kernel opcode 2)
58
+ int 80h ; call the kernel
59
+
60
+ cmp eax , 0 ; if return value of SYS_FORK in eax is zero we are in the child process
61
+ jz .read ; jmp in child process to _read
62
+
63
+ jmp .accept ; jmp in parent process to _accept
64
+
65
+ ;Read the sent request
66
+ .read:
67
+ mov edx , 255 ; number of bytes to read (we will only read the first 255 bytes for simplicity)
68
+ mov ecx , buffer ; move the memory address of our buffer variable into ecx
69
+ mov ebx , esi ; move esi into ebx (accepted socket file descriptor)
70
+ mov eax , 3 ; invoke SYS_READ (kernel opcode 3)
71
+ int 80h ; call the kernel
72
+
73
+ mov eax , buffer ; move the memory address of our buffer variable into eax for printing
74
+ call sprintLF ; call our string printing function
75
+
76
+ ;Send the value of the request to the socket
77
+ mov edx , 80 ; move 80 dec into edx (length in bytes to write)
78
+ mov ecx , response ; move address of our response variable into ecx
79
+ mov ebx , esi ; move file descriptor into ebx (accepted socket id)
80
+ mov eax , 4 ; invoke SYS_WRITE (kernel opcode 4)
81
+ int 80h ; call the kernel
82
+
83
+ ;Close the socket
84
+ mov ebx , esi ; move esi into ebx (accepted socket file descriptor)
85
+ mov eax , 6 ; invoke SYS_CLOSE (kernel opcode 6)
86
+ int 80h ; call the kernel
87
+ ret
88
+
89
+ ; Takes:
90
+ ; eax: address of argv[1]
91
+ ; Sets the value of the socket varibale to argv[1] in reverse byte order
92
+ SetSocketFromArg:
93
+ mov eax , [ eax ]
94
+ push eax
95
+ sub al , 0x30
96
+ sub ah , 0x30
97
+ shl al , 4
98
+ add al , ah
99
+ movzx bx , al
100
+ pop eax
101
+ shr eax , 16
102
+ sub al , 0x30
103
+ sub ah , 0x30
104
+ shl al , 4
105
+ add al , ah
106
+ shl bx , 8
107
+ and ax , 0xFF
108
+ add bx , ax
109
+ movzx eax , bx
110
+ call GetDecimalValueFromHex
111
+ xchg dh , dl
112
+ mov [ socket ], dx
113
+ ret
0 commit comments