Well I finally managed to get my "bind" working (a simple case of forgetting to put [ ] around my label :3) so maybe the following code will be of use to you:
This is not X11 system /related as far as im aware
Using the normal
int 0x80 linux interrupt:
- eax has the value 102 (for sys_socket)
- ebx contains a socket sub-call (socket, bind, listen, connect, accept and a couple of others)
- ecx is a pointer to values.
The first sub-call (
ebx, 1) is socket(), which provides us with a socket-based file descriptor. Socket() is listed as:
- int socket(int domain, int type, int protocol)
For a IPv4 socket run as TCP then Socket() is:
- Socket (AF_INET, SOCK_STREAM, TCP)
- Socket (2, 1, 6)
Socket() returns a 32bit (dword) file descriptor (sockfd) in
eaxOur second sub-call
ebx, 2 is bind(), which associates our socket (sockfd) with a local address (IP:port basically for IPv4). Bind() is listed as:
- int bind(int sockfd, struct sockaddr *my_addr, socklen_t addrlen)
i.e.
- int bind(sockfd, pointer to sockaddr, length of sockaddr)
- sockfd is the file descriptor passed into eax from the linux kernel after socket().
- 'pointer' is a 32bit pointer to the sockaddr structure
- 'length' is 32bit value representing the number of bytes the sockaddr structure is made of (which should be 16 for IPv4)
sockaddr for IPv4 (sockaddr_in) is:
- sin_family
- sin_port
- sin_addr
- padding
i.e.:
- (16bit) AF_INET
- 16bit port number, network byte order
- 32bit IP address, network byte order
- 64bit of 0's for padding
implimented for me as:
- 2
- 0x5000
- 0x2717155E
- 0x0000000000000000
translated:
- AF_INET address family (IPv4)
- Port 80 (HTTP)
- 94.23.21.39 (my server's IP)
- 00000000 padding for future proofing
So the above which is implimented in the source (in bold) would set sockaddr for the IP:port pair 94.23.21.39:80 under AF_INET (IPv4) with padding (which is mostly unnecessary /not implimented)
We push sockaddr to the stack first, save the current location of esp since this is our pointer in bind():
as per my source bind() is:
^ Names are labels since i stored them into memory. "socket" is therefore where i stored sockfd and sock_address is where i stored the stack pointer (esp) after pushing the sockaddr structure onto the stack.
Listen() and accept() should be easy enough to understand if you read the manual pages i linked to before (if not, just ask!
) You do not use listen on the client side (use connect() for that). You then just read/write to the sockfd as you would do normally. You get a new sockfd from accept (since listen()/accep() is server orientated and there are multiple clients connecting to one server so there needs to be some form of isolating each one)
Network byte order (big endian) is important and worth a read, the IP and port needs to be in network byte order and is generally best done with hex values
Pushing to the stack is done "backwards" because it will be read in the opposit direction (last in, first out) and will therefore be read in the 'correct' direction by th linux kernel. So where socket() is : AF_INET, SOCK_STREAM, TCP you push it on the stack in this order: TCP, SOCK_STREAM, AF_INET.
note that none of this has error checking ! port 80 is restricted to root user (effective user ID 0) so it will complain if you try running the source on a normal user.
global _start
section .text
_start:
;------------------------------------------
;socket()
push dword 6
push dword 1
push dword 2
;system call socket
mov eax, 102
mov ebx, 1
mov ecx, esp
int 0x80
;------------------------------------------
section .bss
socket: resd 1
connection: resd 1
socket_address: resd 2
;------------------------------------------
section .text
mov Dword [socket],eax
;------------------------------------------
;sockaddr
push qword 0
push dword 0x2717155E ; network byte order
push word 0x5000 ;network byte order
push word 2
;pointer to sockaddr
mov [socket_address],esp
;bind()
push dword 16
push dword [socket_address]
push dword [socket]
;systemcall bind()
mov eax, 102
mov ebx, 2
mov ecx, esp
int 0x80
;------------------------------------------
;listen()
push byte 20
push dword [socket]
;systemcall listen()
mov eax, 102
mov ebx, 4
mov ecx, esp
int 0x80
;------------------------------------------
;accept()
push 0
push 0
push dword [socket]
;systemcall accept()
mov eax, 102
mov ebx, 5
mov ecx, esp
int 0x80