Reputation: 97
I'm starting to program network programs in asm (NASM) and technically, the accept function block the program (passive socket). Well, in my program I execute the program and the program finish. I've tested setting the backlog to 1 (listen function), but it's not the problem... What happen?
BITS 32
section .text
global _start
_start:
; Create the socket file descriptor
; int socket(int domain, int type, int protocol);
mov eax, 102 ; __NR_socketcall
mov ebx, 1 ; socketcall type (socket)
; socket parameters
push 0 ; IPPROTO_TCP
push 1 ; SOCK_STREAM
push 2 ; AF_INET
int 0x80 ; socket(AF_INET, SOCK_STREAM, IPPROTO_TCP)
mov edx, eax ; edx = socketfd
; Bind the socket with an address type
; int bind(int sockfd, const struct sockaddr *addr, socklen_t addrlen);
mov eax, 102 ; __NR_socketcall
mov ebx, 2 ; socketcall type (bind)
; build the sockaddr_in struct
push 0 ; INADDR_ANY
push WORD 0x0457 ; port 1111
push WORD 2 ; AF_INET
mov ecx, esp ; struct ptr
; bind parameters
push 16 ; sockaddr struct size = sizeof(struct sockaddr) = 16
push ecx ; sockaddr_in struct ptr
push edx ; socket fd
int 0x80 ; bind(sockfd, {AF_INET, 11111, INADDR_ANY}, 16)
; Prepare to listen the incoming connection (passive socket)
; int listen(int sockfd, int backlog);
mov eax, 102 ; __NR_socketcall
mov ebx, 4 ; socketcall type (listen)
; listen parameters
push 0 ; nº connections in the waiting queue (0 = accept and we haven't queue)
push edx ; socket fd
int 0x80 ; listen(sockfd, 0);
; Accept the incoming connection
; int accept(int sockfd, struct sockaddr *addr, socklen_t *addrlen);
mov eax, 102 ; __NR_socketcall
mov ebx, 5 ; socketcall type (accept)
; accept parameters
push 0
push 0
push edx ; socket fd
int 0x80 ; accept(sockfd, NULL, NULL)
; Exit
; int exit(int status)
mov eax, 1 ; __NR_exit
mov ebx, 0 ; exit code
int 0x80
Upvotes: 2
Views: 134
Reputation: 94789
you're missing a mov ecx, esp
after the last push for each of your argument pushes, as well as htons
'ing the port number. A fixed version of you code should look like:
BITS 32
section .text
global _start
_start:
; Create the socket file descriptor
; int socket(int domain, int type, int protocol);
mov eax, 102 ; __NR_socketcall
mov ebx, 1 ; socketcall type (socket)
; socket parameters
push 6 ; IPPROTO_TCP
push 1 ; SOCK_STREAM
push 2 ; AF_INET
mov ecx, esp ; <<== uargs* in ecx
int 0x80 ; socket(AF_INET, SOCK_STREAM, IPPROTO_TCP)
mov edx, eax ; edx = socketfd
; Bind the socket with an address type
; int bind(int sockfd, const struct sockaddr *addr, socklen_t addrlen);
mov eax, 102 ; __NR_socketcall
mov ebx, 2 ; socketcall type (bind)
; build the sockaddr_in struct
push 0 ; INADDR_ANY
push WORD 0x5704 ; port 1111 == htons(1111)
push WORD 2 ; AF_INET
mov ecx, esp ; struct ptr
; bind parameters
push 16 ; sockaddr struct size = sizeof(struct sockaddr) = 16
push ecx ; sockaddr_in struct ptr
push edx ; socket fd
mov ecx, esp ; <<== uargs* in ecx
int 0x80 ; bind(sockfd, {AF_INET, 11111, INADDR_ANY}, 16)
; Prepare to listen the incoming connection (passive socket)
; int listen(int sockfd, int backlog);
mov eax, 102 ; __NR_socketcall
mov ebx, 4 ; socketcall type (listen)
; listen parameters
push 0 ; nº connections in the waiting queue (0 = accept and we haven't queue)
push edx ; socket fd
mov ecx, esp ; <<== uargs* in ecx
int 0x80 ; listen(sockfd, 0);
; Accept the incoming connection
; int accept(int sockfd, struct sockaddr *addr, socklen_t *addrlen);
mov eax, 102 ; __NR_socketcall
mov ebx, 5 ; socketcall type (accept)
; accept parameters
push 0
push 0
push edx ; socket fd
mov ecx, esp ; struct ptr
int 0x80 ; accept(sockfd, NULL, NULL)
; Exit
; int exit(int status)
mov eax, 1 ; __NR_exit
mov ebx, 0 ; exit code
int 0x80
In this case it would have been important that you did an strace
on your program to verify that you were seeing the correct parameters being processed in the system call.
If we strace
your original program we get:
socket(PF_UNSPEC, 0, 0) = -1 EFAULT (Bad address)
bind(1459879938, NULL, 2) = -1 EBADF (Bad file descriptor)
listen(1459879938, 0) = -1 EBADF (Bad file descriptor)
accept(1459879938, 0, 0x2) = -1 EBADF (Bad file descriptor)
all of which looks like things went very badly.
If you look at the source for compat_sys_socketcall
it shows:
asmlinkage long compat_sys_socketcall(int call, u32 __user *args)
which means EBX is the call and ECX points to the remainder of the arguments.
Upvotes: 2