Subversion Repositories Kolibri OS

Compare Revisions

Regard whitespace Rev 3657 → Rev 3658

/kernel/trunk/network/socket.inc
17,7 → 17,17
 
$Revision: 3514 $
 
ENOBUFS = 1
EOPNOTSUPP = 4
EWOULDBLOCK = 6
ENOTCONN = 9
EALREADY = 10
EINVAL = 11
EMSGSIZE = 12
ENOMEM = 18
EADDRINUSE = 20
 
 
struct SOCKET
 
NextPtr dd ? ; pointer to next socket in list
250,7 → 260,7
jz SOCKET_debug
 
cmp ebx, .number
ja s_error
ja .error
jmp dword [.table + 4*ebx]
 
.table:
267,9 → 277,9
dd SOCKET_pair ; 10
.number = ($ - .table) / 4 - 1
 
s_error:
DEBUGF DEBUG_NETWORK_ERROR, "SOCKET: error\n"
.error:
mov dword [esp+32], -1
mov dword[esp+24], EINVAL
 
ret
 
291,7 → 301,7
push ecx edx esi
call SOCKET_alloc
pop esi edx ecx
jz s_error
jz .nobuffs
 
mov [esp+32], edi ; return socketnumber
DEBUGF DEBUG_NETWORK_VERBOSE, "socknum=%u\n", edi
326,25 → 336,28
je .pppoe
 
.no_ppp:
DEBUGF DEBUG_NETWORK_ERROR, "SOCKET_open: Unknown socket family/protocol\n"
.unsupported:
push eax
call SOCKET_free
pop eax
mov dword[esp+24], EOPNOTSUPP
mov dword[esp+32], -1
ret
 
align 4
.nobuffs:
mov dword[esp+24], ENOBUFS
mov dword[esp+32], -1
ret
 
.raw:
test esi, esi ; IP_PROTO_IP
jz .ip
jz .raw_ip
 
cmp esi, IP_PROTO_ICMP
je .icmp
je .raw_icmp
 
cmp esi, IP_PROTO_UDP
je .udp
jmp .unsupported
 
cmp esi, IP_PROTO_TCP
je .tcp
 
ret
 
align 4
.udp:
mov [eax + SOCKET.Protocol], IP_PROTO_UDP
363,7 → 376,7
 
 
align 4
.ip:
.raw_ip:
mov [eax + SOCKET.snd_proc], SOCKET_send_ip
mov [eax + SOCKET.rcv_proc], SOCKET_receive_dgram
ret
370,7 → 383,7
 
 
align 4
.icmp:
.raw_icmp:
mov [eax + SOCKET.snd_proc], SOCKET_send_icmp
mov [eax + SOCKET.rcv_proc], SOCKET_receive_dgram
ret
402,10 → 415,10
DEBUGF DEBUG_NETWORK_VERBOSE, "SOCKET_bind: socknum=%u sockaddr=%x length=%u\n", ecx, edx, esi
 
call SOCKET_num_to_ptr
jz s_error
jz .invalid
 
cmp esi, 2
jb s_error
jb .invalid
 
cmp word [edx], AF_INET4
je .af_inet4
413,18 → 426,24
cmp word [edx], AF_LOCAL
je .af_local
 
jmp s_error
.notsupp:
mov dword[esp+24], EOPNOTSUPP
mov dword[esp+32], -1
ret
 
.invalid:
mov dword[esp+24], EINVAL
mov dword[esp+32], -1
ret
 
.af_local:
; TODO: write code here
 
mov dword [esp+32], 0
ret
 
.af_inet4:
 
cmp esi, 6
jb s_error
jb .invalid
 
cmp [eax + SOCKET.Protocol], IP_PROTO_UDP
je .udp
432,11 → 451,10
cmp [eax + SOCKET.Protocol], IP_PROTO_TCP
je .tcp
 
jmp s_error
jmp .notsupp
 
.tcp:
.udp:
 
mov ebx, [edx + 4] ; First, fill in the IP
test ebx, ebx ; If IP is 0, use default
jnz @f
446,7 → 464,7
 
mov bx, [edx + 2] ; Now fill in the local port if it's still available
call SOCKET_check_port
jz s_error ; ZF is set by socket_check_port, on error
jz .addrinuse ; ZF is set by socket_check_port, on error
 
DEBUGF DEBUG_NETWORK_VERBOSE, "SOCKET_bind: local ip=%u.%u.%u.%u\n",\
[eax + IP_SOCKET.LocalIP + 0]:1,[eax + IP_SOCKET.LocalIP + 1]:1,\
455,9 → 473,14
mov dword [esp+32], 0
ret
 
.addrinuse:
mov dword[esp+32], -1
mov dword[esp+24], EADDRINUSE
ret
 
 
 
 
;-----------------------------------------------------------------
;
; SOCKET_connect
474,16 → 497,24
DEBUGF DEBUG_NETWORK_VERBOSE, "SOCKET_connect: socknum=%u sockaddr=%x length=%u\n", ecx, edx, esi
 
call SOCKET_num_to_ptr
jz s_error
jz .invalid
 
cmp esi, 8
jb s_error
jb .invalid
 
cmp word [edx], AF_INET4
je .af_inet4
 
jmp s_error
.notsupp:
mov dword[esp+24], EOPNOTSUPP
mov dword[esp+32], -1
ret
 
.invalid:
mov dword[esp+24], EINVAL
mov dword[esp+32], -1
ret
 
.af_inet4:
cmp [eax + IP_SOCKET.LocalIP], 0
jne @f
503,7 → 534,7
cmp [eax + SOCKET.Protocol], IP_PROTO_ICMP
je .ip
 
jmp s_error
jmp .notsupp
 
align 4
.udp:
569,10 → 600,10
mov ebx, eax
 
lea eax, [ebx + STREAM_SOCKET.snd]
call SOCKET_ring_create
call SOCKET_ring_create ; TODO: check if memory was available or not
 
lea eax, [ebx + STREAM_SOCKET.rcv]
call SOCKET_ring_create
call SOCKET_ring_create ; TODO: same here
 
pusha
lea ecx, [ebx + SOCKET.mutex]
623,16 → 654,16
DEBUGF DEBUG_NETWORK_VERBOSE, "SOCKET_listen: socknum=%u backlog=%u\n", ecx, edx
 
call SOCKET_num_to_ptr
jz s_error
jz .invalid
 
cmp [eax + SOCKET.Domain], AF_INET4
jne s_error
jne .notsupp
 
cmp [eax + SOCKET.Protocol], IP_PROTO_TCP
jne s_error
jne .invalid
 
cmp [eax + TCP_SOCKET.LocalPort], 0
je s_error
je .already
 
cmp [eax + IP_SOCKET.LocalIP], 0
jne @f
655,10 → 686,24
pop eax
 
mov dword [esp+32], 0
ret
 
.notsupp:
mov dword[esp+24], EOPNOTSUPP
mov dword[esp+32], -1
ret
 
.invalid:
mov dword[esp+24], EINVAL
mov dword[esp+32], -1
ret
 
.already:
mov dword[esp+24], EALREADY
mov dword[esp+32], -1
ret
 
 
;-----------------------------------------------------------------
;
; SOCKET_accept
675,16 → 720,16
DEBUGF DEBUG_NETWORK_VERBOSE, "SOCKET_accept: socknum=%u sockaddr=%x length=%u\n", ecx, edx, esi
 
call SOCKET_num_to_ptr
jz s_error
jz .invalid
 
test [eax + SOCKET.options], SO_ACCEPTCON
jz s_error
jz .invalid
 
cmp [eax + SOCKET.Domain], AF_INET4
jne s_error
jne .notsupp
 
cmp [eax + SOCKET.Protocol], IP_PROTO_TCP
jne s_error
jne .invalid
 
.loop:
get_from_queue (eax + SOCKET_QUEUE_LOCATION), MAX_backlog, 4, .block
692,14 → 737,15
; Ok, we got a socket ptr
mov eax, [esi]
 
; Convert it to a socket number
call SOCKET_ptr_to_num
jz .invalid ; FIXME ?
 
; Change thread ID to that of the current thread
mov ebx, [TASK_BASE]
mov ebx, [ebx + TASKDATA.pid]
mov [eax + SOCKET.TID], ebx
 
; Convert it to a socket number
call SOCKET_ptr_to_num
jz s_error
; and return it to caller
mov [esp+32], eax
ret
706,11 → 752,26
 
.block:
test [eax + SOCKET.options], SO_NONBLOCK
jnz s_error
jnz .wouldblock
 
call SOCKET_block
jmp .loop
 
.wouldblock:
mov dword[esp+24], EWOULDBLOCK
mov dword[esp+32], -1
ret
 
.invalid:
mov dword[esp+24], EINVAL
mov dword[esp+32], -1
ret
 
.notsupp:
mov dword[esp+24], EOPNOTSUPP
mov dword[esp+32], -1
ret
 
;-----------------------------------------------------------------
;
; SOCKET_close
725,7 → 786,7
DEBUGF DEBUG_NETWORK_VERBOSE, "SOCKET_close: socknum=%u\n", ecx
 
call SOCKET_num_to_ptr
jz s_error
jz .invalid
 
mov dword [esp+32], 0 ; The socket exists, so we will succeed in closing it.
 
757,6 → 818,12
ret
 
 
.invalid:
mov dword[esp+24], EINVAL
mov dword[esp+32], -1
ret
 
 
;-----------------------------------------------------------------
;
; SOCKET_receive
774,17 → 841,22
DEBUGF DEBUG_NETWORK_VERBOSE, "SOCKET_receive: socknum=%u bufaddr=%x buflength=%u flags=%x\n", ecx, edx, esi, edi
 
call SOCKET_num_to_ptr
jz s_error
jz .invalid
 
call [eax + SOCKET.rcv_proc]
 
mov [esp+24], ebx
mov [esp+32], eax
ret
 
 
.invalid:
mov dword[esp+24], EINVAL
mov dword[esp+32], -1
ret
 
align 4
SOCKET_receive_dgram:
 
DEBUGF DEBUG_NETWORK_VERBOSE, "SOCKET_receive: DGRAM\n"
 
mov ebx, esi
820,24 → 892,26
 
call kernel_free ; remove the packet
pop eax
 
ret
 
.too_small:
 
DEBUGF DEBUG_NETWORK_VERBOSE, "SOCKET_receive: Buffer too small\n"
.fail:
mov eax, -1
mov ebx, EMSGSIZE
ret
 
.block:
test [eax + SOCKET.options], SO_NONBLOCK
jnz .fail
jnz .wouldblock
 
call SOCKET_block
jmp .loop
 
.wouldblock:
mov eax, -1
mov ebx, EWOULDBLOCK
ret
 
 
align 4
SOCKET_receive_local:
 
886,7 → 960,7
 
.block:
test [eax + SOCKET.options], SO_NONBLOCK
jnz .return0
jnz .wouldblock
 
call SOCKET_block
jmp .loop
903,7 → 977,13
xor eax, eax
ret
 
.wouldblock:
mov eax, -1
mov ebx, EWOULDBLOCK
ret
 
 
 
;-----------------------------------------------------------------
;
; SOCKET_send
922,7 → 1002,7
DEBUGF DEBUG_NETWORK_VERBOSE, "SOCKET_send: socknum=%u data ptr=%x length=%u flags=%x\n", ecx, edx, esi, edi
 
call SOCKET_num_to_ptr
jz s_error
jz .invalid
 
mov ecx, esi
mov esi, edx
929,7 → 1009,12
 
jmp [eax + SOCKET.snd_proc]
 
.invalid:
mov dword[esp+24], EINVAL
mov dword[esp+32], -1
ret
 
 
align 4
SOCKET_send_udp:
 
938,10 → 1023,15
mov [esp+32], ecx
call UDP_output
cmp eax, -1
je s_error
je .error
ret
 
.error:
mov dword[esp+32], -1
mov dword[esp+24], EMSGSIZE ; FIXME: UDP_output should return error codes!
ret
 
 
align 4
SOCKET_send_tcp:
 
953,8 → 1043,12
pop eax
 
mov [esp+32], ecx
 
call TCP_output
mov [eax + SOCKET.errorcode], 0
push eax
call TCP_output ; FIXME: this doesnt look pretty, does it?
pop eax
mov eax, [eax + SOCKET.errorcode]
mov [esp+24], eax
ret
 
 
964,12 → 1058,17
DEBUGF DEBUG_NETWORK_VERBOSE, "SOCKET_send: IPv4\n"
 
mov [esp+32], ecx
call IPv4_output_raw
call IPv4_output_raw ; FIXME: IPv4_output_raw should return error codes!
cmp eax, -1
je s_error
je .error
ret
 
.error:
mov dword[esp+32], -1
mov dword[esp+24], EMSGSIZE
ret
 
 
align 4
SOCKET_send_icmp:
 
976,12 → 1075,17
DEBUGF DEBUG_NETWORK_VERBOSE, "SOCKET_send: ICMP\n"
 
mov [esp+32], ecx
call ICMP_output_raw
call ICMP_output_raw ; FIXME: errorcodes
cmp eax, -1
je s_error
je .error
ret
 
.error:
mov dword[esp+32], -1
mov dword[esp+24], EMSGSIZE
ret
 
 
align 4
SOCKET_send_pppoe:
 
990,13 → 1094,18
mov [esp+32], ecx
mov ebx, [eax + SOCKET.device]
 
call PPPoE_discovery_output
call PPPoE_discovery_output ; FIXME: errorcodes
cmp eax, -1
je s_error
je .error
ret
 
.error:
mov dword[esp+32], -1
mov dword[esp+24], EMSGSIZE
ret
 
 
 
align 4
SOCKET_send_local:
 
1020,7 → 1129,7
; get the other side's socket and check if it still exists
mov eax, [eax + SOCKET.device]
call SOCKET_check
jz s_error
jz .invalid
 
; allright, shove in the data!
push eax
1036,7 → 1145,12
 
ret
 
.invalid:
mov dword[esp+32], -1
mov dword[esp+24], EINVAL
ret
 
 
;-----------------------------------------------------------------
;
; SOCKET_get_options
1057,14 → 1171,14
DEBUGF DEBUG_NETWORK_VERBOSE, "SOCKET_get_opt\n"
 
call SOCKET_num_to_ptr
jz s_error
jz .invalid
 
cmp dword [edx], IP_PROTO_TCP
jne s_error
jne .invalid
cmp dword [edx+4], -2
je @f
cmp dword [edx+4], -3
jne s_error
jne .invalid
@@:
; mov eax, [edx+12]
; test eax, eax
1089,8 → 1203,13
mov dword [esp+32], 0
ret
 
.invalid:
mov dword[esp+32], -1
mov dword[esp+24], EINVAL
ret
 
 
 
;-----------------------------------------------------------------
;
; SOCKET_set_options
1107,10 → 1226,10
DEBUGF DEBUG_NETWORK_VERBOSE, "SOCKET_set_opt\n"
 
call SOCKET_num_to_ptr
jz s_error
jz .invalid
 
cmp dword [edx], SOL_SOCKET
jne s_error
jne .invalid
 
cmp dword [edx+4], SO_BINDTODEVICE
je .bind
1118,7 → 1237,10
cmp dword [edx+4], SO_BLOCK
je .block
 
jmp s_error
.invalid:
mov dword[esp+32], -1
mov dword[esp+24], EINVAL
ret
 
.bind:
cmp dword [edx+8], 0
1126,11 → 1248,11
 
movzx edx, byte [edx + 9]
cmp edx, NET_DEVICES_MAX
ja s_error
ja .invalid
 
mov edx, [NET_DRV_LIST + 4*edx]
test edx, edx
jz s_error
jz .already
mov [eax + SOCKET.device], edx
 
DEBUGF DEBUG_NETWORK_VERBOSE, "SOCKET_set_opt: Bound socket %x to device %x\n",eax, edx
1159,8 → 1281,14
mov dword [esp+32], 0 ; success!
ret
 
.already:
mov dword[esp+24], EALREADY
mov dword[esp+32], -1
ret
 
 
 
 
;-----------------------------------------------------------------
;
; SOCKET_pair
1178,7 → 1306,7
DEBUGF DEBUG_NETWORK_VERBOSE, "SOCKET_pair\n"
 
call SOCKET_alloc
jz s_error
jz .nomem1
mov [esp+32], edi ; application's eax
 
mov [eax + SOCKET.Domain], AF_LOCAL
1190,7 → 1318,7
mov ebx, eax
 
call SOCKET_alloc
jz .error
jz .nomem2
mov [esp+24], edi ; application's ebx
 
mov [eax + SOCKET.Domain], AF_LOCAL
1213,10 → 1341,13
 
ret
 
.error:
.nomem2:
mov eax, ebx
call SOCKET_free
jmp s_error
.nomem1:
mov dword[esp+32], -1
mov dword[esp+28], ENOMEM
ret
 
 
 
1242,7 → 1373,7
jz .returnall
 
call SOCKET_num_to_ptr
jz s_error
jz .invalid
 
mov esi, eax
mov ecx, SOCKETBUFFSIZE/4
1263,8 → 1394,12
.done:
xor eax, eax
stosd
mov dword[esp+32], eax
ret
 
mov dword [esp+32], 0
.invalid:
mov dword[esp+32], -1
mov dword[esp+28], EINVAL
ret
 
 
1830,8 → 1965,8
pop eax
 
; set send-and receive procedures to return -1
mov [eax + SOCKET.snd_proc], s_error
mov [eax + SOCKET.rcv_proc], s_error
mov [eax + SOCKET.snd_proc], .not_yet
mov [eax + SOCKET.rcv_proc], .not_yet
 
pusha
mov ecx, socket_mutex
1907,7 → 2042,12
 
ret
 
.not_yet:
mov dword[esp+24], ENOTCONN
mov dword[esp+32], -1
ret
 
 
;----------------------------------------------------
;
; SOCKET_free
2391,8 → 2531,13
DEBUGF DEBUG_NETWORK_VERBOSE, "SOCKET_cant_send_more: %x\n", eax
 
or [eax + SOCKET.options], SS_CANTSENDMORE
mov [eax + SOCKET.snd_proc], s_error
mov [eax + SOCKET.snd_proc], .notconn
 
call SOCKET_notify
 
ret
 
.notconn:
mov dword[esp+24], ENOTCONN
mov dword[esp+32], -1
ret