Subversion Repositories Kolibri OS

Compare Revisions

Regard whitespace Rev 3724 → Rev 3725

/kernel/branches/Kolibri-acpi/network/ARP.inc
55,10 → 55,9
 
ends
 
uglobal
align 4
uglobal
 
 
ARP_table rb NET_DEVICES_MAX*(ARP_TABLE_SIZE * sizeof.ARP_entry)
 
ARP_entries_num rd NET_DEVICES_MAX
176,13 → 175,13
cmp ecx, sizeof.ARP_header
jb .exit
 
call NET_ptr_to_num
call NET_ptr_to_num4
cmp edi, -1
jz .exit
 
inc [ARP_PACKETS_RX + 4*edi] ; update stats
inc [ARP_PACKETS_RX + edi] ; update stats
 
DEBUGF DEBUG_NETWORK_VERBOSE, "ARP_input: got packet from %u.%u.%u.%u through device %u\n",\
DEBUGF DEBUG_NETWORK_VERBOSE, "ARP_input: got packet from %u.%u.%u.%u (device*4=%u)\n",\
[edx + ARP_header.SenderIP]:1, [edx + ARP_header.SenderIP + 1]:1,\
[edx + ARP_header.SenderIP + 2]:1, [edx + ARP_header.SenderIP + 3]:1, edi
 
190,7 → 189,7
; First, check for IP collision
 
mov eax, [edx + ARP_header.SenderIP]
cmp eax, [IP_LIST + 4*edi]
cmp eax, [IP_LIST + edi]
je .collision
 
;---------------------
201,12 → 200,12
 
DEBUGF DEBUG_NETWORK_VERBOSE, "ARP_input: It's a reply\n"
 
mov ecx, [ARP_entries_num + 4*edi]
mov ecx, [ARP_entries_num + edi]
test ecx, ecx
jz .exit
 
mov esi, (ARP_TABLE_SIZE * sizeof.ARP_entry)
imul esi, edi
mov esi, edi
imul esi, (ARP_TABLE_SIZE * sizeof.ARP_entry)/4
add esi, ARP_table
.loop:
cmp [esi + ARP_entry.IP], eax
245,7 → 244,7
 
DEBUGF DEBUG_NETWORK_VERBOSE, "ARP_input: its a request\n"
 
mov eax, [IP_LIST + 4*edi]
mov eax, [IP_LIST + edi]
cmp eax, [edx + ARP_header.TargetIP] ; Is it looking for my IP address?
jne .exit
 
262,7 → 261,7
movsd ; Move sender IP to Dest IP
 
pop esi
mov esi, [NET_DRV_LIST + 4*esi]
mov esi, [NET_DRV_LIST + esi]
lea esi, [esi + ETH_DEVICE.mac]
lea edi, [edx + ARP_header.SenderMAC]
movsd ; Copy MAC address from in MAC_LIST
290,7 → 289,7
ret
 
.collision:
inc [ARP_CONFLICTS + 4*edi]
inc [ARP_CONFLICTS + edi]
DEBUGF DEBUG_NETWORK_VERBOSE, "ARP_input: IP address conflict detected!\n"
 
.exit:
337,11 → 336,11
movsw ;
movsd ;
 
; mov esi, [ebx + NET_DEVICE.number]
xor esi, esi ;;;; FIXME
inc esi ;;;;;;;;;
inc [ARP_PACKETS_TX + 4*esi] ; assume we will succeed
lea esi, [IP_LIST + 4*esi] ; SenderIP
push edi
call NET_ptr_to_num4
inc [ARP_PACKETS_TX + edi] ; assume we will succeed
lea esi, [IP_LIST + edi] ; SenderIP
pop edi
movsd
 
mov esi, ETH_BROADCAST ; DestMac
364,7 → 363,7
; ARP_add_entry (or update)
;
; IN: esi = ptr to entry (can easily be made on the stack)
; edi = device num
; edi = device num*4
; OUT: eax = entry #, -1 on error
; esi = ptr to newly created entry
;
374,17 → 373,17
 
DEBUGF DEBUG_NETWORK_VERBOSE, "ARP_add_entry: device=%u\n", edi
 
mov ecx, [ARP_entries_num + 4*edi]
mov ecx, [ARP_entries_num + edi]
cmp ecx, ARP_TABLE_SIZE ; list full ?
jae .full
 
; From this point on, we can only fail if IP has a static entry, or if table is corrupt.
 
inc [ARP_entries_num + 4*edi] ; assume we will succeed
inc [ARP_entries_num + edi] ; assume we will succeed
 
push edi
xor ecx, ecx
imul edi, ARP_TABLE_SIZE*sizeof.ARP_entry
imul edi, ARP_TABLE_SIZE*sizeof.ARP_entry/4
add edi, ARP_table
mov eax, [esi + ARP_entry.IP]
.loop:
419,7 → 418,7
 
.error:
pop edi
dec [ARP_entries_num + 4*edi]
dec [ARP_entries_num + edi]
DEBUGF DEBUG_NETWORK_ERROR, "ARP_add_entry_failed\n"
.full:
mov eax, -1
475,7 → 474,7
; This function translates an IP address to a MAC address
;
; IN: eax = IPv4 address
; edi = device number
; edi = device number * 4
; OUT: eax = -1 on error, -2 means request send
; else, ax = first two bytes of mac (high 16 bits of eax will be 0)
; ebx = last four bytes of mac
487,7 → 486,7
 
DEBUGF DEBUG_NETWORK_VERBOSE, "ARP_IP_to_MAC: %u.%u", al, ah
rol eax, 16
DEBUGF DEBUG_NETWORK_VERBOSE, ".%u.%u device: %u\n", al, ah, edi
DEBUGF DEBUG_NETWORK_VERBOSE, ".%u.%u device*4: %u\n", al, ah, edi
rol eax, 16
 
cmp eax, 0xffffffff
496,11 → 495,11
;--------------------------------
; Try to find the IP in ARP_table
 
mov ecx, [ARP_entries_num + 4*edi]
mov ecx, [ARP_entries_num + edi]
test ecx, ecx
jz .not_in_list
mov esi, edi
imul esi, sizeof.ARP_entry * ARP_TABLE_SIZE
imul esi, (sizeof.ARP_entry * ARP_TABLE_SIZE)/4
add esi, ARP_table + ARP_entry.IP
.scan_loop:
cmp [esi], eax
538,7 → 537,7
pop edi eax ; IP in eax, device number in ebx, for ARP_output_request
 
push esi edi
mov ebx, [NET_DRV_LIST + 4*edi]
mov ebx, [NET_DRV_LIST + edi]
call ARP_output_request
pop edi esi
.found_it:
655,7 → 654,6
.write:
; esi = pointer to buffer
mov edi, eax
shr edi, 2
call ARP_add_entry ; out: eax = entry number, -1 on error
ret
 
/kernel/branches/Kolibri-acpi/network/IPv4.inc
55,8 → 55,8
ends
 
 
uglobal
align 4
uglobal
 
IP_LIST rd NET_DEVICES_MAX
SUBNET_LIST rd NET_DEVICES_MAX
69,6 → 69,7
IP_packets_dumped rd NET_DEVICES_MAX
 
FRAGMENT_LIST rb MAX_FRAGMENTS * sizeof.FRAGMENT_slot
 
endg
 
 
223,8 → 224,7
;-----------------------------------
; Check if destination IP is correct
 
call NET_ptr_to_num
shl edi, 2
call NET_ptr_to_num4
 
; check if it matches local ip (Using RFC1122 strong end system model)
 
586,9 → 586,9
push ebx ; push the mac onto the stack
push ax
 
inc [IP_packets_tx + 4*edi] ; update stats
inc [IP_packets_tx + edi] ; update stats
 
mov ebx, [NET_DRV_LIST + 4*edi]
mov ebx, [NET_DRV_LIST + edi]
lea eax, [ebx + ETH_DEVICE.mac]
mov edx, esp
mov ecx, [esp + 10 + 6]
857,7 → 857,7
; IPv4_route
;
; IN: eax = Destination IP
; OUT: edi = device number
; OUT: edi = device number*4
; eax = ip of gateway if nescessary, unchanged otherwise
;
;---------------------------------------------------------------------------
890,8 → 890,7
.invalid:
mov eax, [GATEWAY_LIST+4] ;;; FIXME
.broadcast:
xor edi, edi ; if none found, use device 1 as default ;;;; FIXME
inc di
mov edi, 4 ; if none found, use device 1 as default ;;;; FIXME
ret
 
 
/kernel/branches/Kolibri-acpi/network/IPv6.inc
30,8 → 30,8
ends
 
 
uglobal
align 4
uglobal
 
IPv6:
.addresses rd 4*NET_DEVICES_MAX
/kernel/branches/Kolibri-acpi/network/PPPoE.inc
23,8 → 23,11
ends
 
uglobal
align 4
 
PPPoE_SID dw ?
PPPoE_MAC dp ?
 
endg
 
;-----------------------------------------------------------------
63,6 → 66,11
 
; First, find open PPPoE socket
 
pusha
mov ecx, socket_mutex
call mutex_lock
popa
 
mov eax, net_sockets
 
.next_socket:
76,6 → 84,11
cmp [eax + SOCKET.Protocol], PPP_PROTO_ETHERNET
jne .next_socket
 
pusha
mov ecx, socket_mutex
call mutex_unlock
popa
 
; Now, send it to the this socket
 
mov ecx, [esp + 4]
84,6 → 97,11
jmp SOCKET_input
 
.dump:
pusha
mov ecx, socket_mutex
call mutex_unlock
popa
 
DEBUGF DEBUG_NETWORK_VERBOSE, 'PPPoE_discovery_input: dumping\n'
call kernel_free
add esp, 4
/kernel/branches/Kolibri-acpi/network/ethernet.inc
32,8 → 32,8
 
ends
 
iglobal
align 4
iglobal
 
ETH_BROADCAST dp 0xffffffffffff
endg
57,9 → 57,8
mov ecx, [esp+4]
 
DEBUGF DEBUG_NETWORK_VERBOSE,"ETH_input: size=%u\n", ecx
cmp ecx, ETH_FRAME_MINIMUM
sub ecx, sizeof.ETH_header
jb .dump
sub ecx, sizeof.ETH_header
 
lea edx, [eax + sizeof.ETH_header]
mov ax, [eax + ETH_header.Type]
/kernel/branches/Kolibri-acpi/network/icmp.inc
97,10 → 97,12
ends
 
 
uglobal
align 4
uglobal
 
ICMP_PACKETS_TX rd NET_DEVICES_MAX
ICMP_PACKETS_RX rd NET_DEVICES_MAX
 
endg
 
 
156,9 → 158,17
pop ecx edx
jne .checksum_mismatch
 
; Check packet type
 
cmp [edx + ICMP_header.Type], ICMP_ECHO ; Is this an echo request?
jne .check_sockets
 
; Update stats (and validate device ptr)
call NET_ptr_to_num4
cmp edi, -1
je .dump
inc [ICMP_PACKETS_RX + edi]
 
; We well re-use the packet so we can create the response as fast as possible
; Notice: this only works on pure ethernet
 
166,14 → 176,6
mov [edx + ICMP_header.Type], ICMP_ECHOREPLY ; Change Packet type to reply
 
mov esi, [esp] ; Start of buffer
 
; Update stats (and validate device ptr)
call NET_ptr_to_num
cmp edi, -1
je .dump
inc [ICMP_PACKETS_RX + 4*edi]
inc [ICMP_PACKETS_TX + 4*edi]
 
cmp ebx, LOOPBACK_DEVICE
je .loopback
 
225,6 → 227,11
 
; Transmit the packet (notice that packet ptr and packet size have been on stack since start of the procedure!)
call [ebx + NET_DEVICE.transmit]
test eax, eax
jnz @f
call NET_ptr_to_num4
inc [UDP_PACKETS_TX + edi]
@@:
ret
 
 
233,6 → 240,11
.check_sockets:
; Look for an open ICMP socket
 
pusha
mov ecx, socket_mutex
call mutex_lock
popa
 
mov esi, [edi] ; ipv4 source address
mov eax, net_sockets
.try_more:
240,7 → 252,7
.next_socket:
mov eax, [eax + SOCKET.NextPtr]
or eax, eax
jz .dump
jz .dump_
 
cmp [eax + SOCKET.Domain], AF_INET4
jne .next_socket
254,11 → 266,17
; cmp [eax + ICMP_SOCKET.Identifier],
; jne .next_socket
 
; call IPv4_dest_to_dev
; cmp edi,-1
; je .dump
; inc [ICMP_PACKETS_RX+edi]
; Update stats (and validate device ptr)
call NET_ptr_to_num4
cmp edi, -1
je .dump_
inc [ICMP_PACKETS_RX + edi]
 
pusha
mov ecx, socket_mutex
call mutex_unlock
popa
 
DEBUGF DEBUG_NETWORK_VERBOSE, "socket=%x\n", eax
 
pusha
269,7 → 287,17
mov esi, edx
jmp SOCKET_input
 
.dump_:
 
pusha
mov ecx, socket_mutex
call mutex_unlock
popa
 
DEBUGF DEBUG_NETWORK_VERBOSE, "ICMP_input: no socket found\n"
jmp .dump
 
 
.checksum_mismatch:
DEBUGF DEBUG_NETWORK_VERBOSE, "checksum mismatch\n"
 
336,6 → 364,11
push edx edi
DEBUGF DEBUG_NETWORK_VERBOSE, "Sending ICMP Packet\n"
call [ebx + NET_DEVICE.transmit]
test eax, eax
jnz @f
call NET_ptr_to_num4
inc [ICMP_PACKETS_TX + edi]
@@:
ret
.exit:
DEBUGF DEBUG_NETWORK_ERROR, "Creating ICMP Packet failed\n"
386,6 → 419,11
 
DEBUGF DEBUG_NETWORK_VERBOSE, "Sending ICMP Packet\n"
call [ebx + NET_DEVICE.transmit]
test eax, eax
jnz @f
call NET_ptr_to_num4
inc [ICMP_PACKETS_TX + edi]
@@:
ret
.exit:
DEBUGF DEBUG_NETWORK_ERROR, "Creating ICMP Packet failed\n"
/kernel/branches/Kolibri-acpi/network/loopback.inc
17,6 → 17,7
$Revision: 2891 $
 
iglobal
align 4
 
LOOPBACK_DEVICE:
 
/kernel/branches/Kolibri-acpi/network/queue.inc
28,6 → 28,7
size dd ? ; number of queued packets in this queue
w_ptr dd ? ; current writing pointer in queue
r_ptr dd ? ; current reading pointer
mutex MUTEX
 
ends
 
44,9 → 45,23
 
macro add_to_queue ptr, size, entry_size, failaddr {
 
local .ok, .no_wrap
 
pusha
lea ecx, [ptr + queue.mutex]
call mutex_lock
popa
 
cmp [ptr + queue.size], size ; Check if queue isnt full
jae failaddr
jb .ok
 
pusha
lea ecx, [ptr + queue.mutex]
call mutex_unlock
popa
jmp failaddr
 
.ok:
inc [ptr + queue.size] ; if not full, queue one more
 
mov edi, [ptr + queue.w_ptr] ; Current write pointer (FIFO!)
58,10 → 73,14
jb .no_wrap
 
sub edi, size*entry_size
 
.no_wrap:
mov [ptr + queue.w_ptr], edi
 
pusha
lea ecx, [ptr + queue.mutex]
call mutex_unlock
popa
 
}
 
 
68,9 → 87,23
 
macro get_from_queue ptr, size, entry_size, failaddr {
 
local .ok, .no_wrap
 
pusha
lea ecx, [ptr + queue.mutex]
call mutex_lock
popa
 
cmp [ptr + queue.size], 0 ; any packets queued?
je failaddr
ja .ok
 
pusha
lea ecx, [ptr + queue.mutex]
call mutex_unlock
popa
jmp failaddr
 
.ok:
dec [ptr + queue.size] ; if so, dequeue one
 
mov esi, [ptr + queue.r_ptr]
89,6 → 122,11
 
pop esi
 
pusha
lea ecx, [ptr + queue.mutex]
call mutex_unlock
popa
 
}
 
macro init_queue ptr {
97,4 → 135,7
lea edi, [ptr + sizeof.queue]
mov [ptr + queue.w_ptr], edi
mov [ptr + queue.r_ptr], edi
 
lea ecx, [ptr + queue.mutex]
call mutex_init
}
/kernel/branches/Kolibri-acpi/network/socket.inc
17,7 → 17,6
 
$Revision$
 
 
struct SOCKET
 
NextPtr dd ? ; pointer to next socket in list
195,10 → 194,14
SOCKET_QUEUE_LOCATION = (SOCKETBUFFSIZE - SOCKET_QUEUE_SIZE*sizeof.socket_queue_entry - sizeof.queue)
 
uglobal
align 4
 
net_sockets rd 4
last_socket_num dd ?
last_UDP_port dw ? ; These values give the number of the last used ephemeral port
last_TCP_port dw ? ;
socket_mutex MUTEX
 
endg
 
 
232,6 → 235,9
xchg al, ah
mov [last_TCP_port], ax
 
mov ecx, socket_mutex
call mutex_init
 
}
 
;-----------------------------------------------------------------
242,11 → 248,13
align 4
sys_socket:
 
mov dword[esp+20], 0 ; Set error code to 0
 
cmp ebx, 255
jz SOCKET_debug
 
cmp ebx, .number
ja s_error
ja .error
jmp dword [.table + 4*ebx]
 
.table:
263,9 → 271,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+20], EINVAL
 
ret
 
287,16 → 295,16
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
 
; push edx
; and edx, SO_NONBLOCK
or [eax + SOCKET.options], SO_NONBLOCK ;edx
; pop edx
; and edx, not SO_NONBLOCK
test edx, SO_NONBLOCK
jz @f
or [eax + SOCKET.options], SO_NONBLOCK
and edx, not SO_NONBLOCK
@@:
 
mov [eax + SOCKET.Domain], ecx
mov [eax + SOCKET.Type], edx
322,25 → 330,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+20], EOPNOTSUPP
mov dword[esp+32], -1
ret
 
align 4
.nobuffs:
mov dword[esp+20], 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
359,7 → 370,7
 
 
align 4
.ip:
.raw_ip:
mov [eax + SOCKET.snd_proc], SOCKET_send_ip
mov [eax + SOCKET.rcv_proc], SOCKET_receive_dgram
ret
366,7 → 377,7
 
 
align 4
.icmp:
.raw_icmp:
mov [eax + SOCKET.snd_proc], SOCKET_send_icmp
mov [eax + SOCKET.rcv_proc], SOCKET_receive_dgram
ret
398,10 → 409,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
409,18 → 420,24
cmp word [edx], AF_LOCAL
je .af_local
 
jmp s_error
.notsupp:
mov dword[esp+20], EOPNOTSUPP
mov dword[esp+32], -1
ret
 
.invalid:
mov dword[esp+20], 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
428,12 → 445,11
cmp [eax + SOCKET.Protocol], IP_PROTO_TCP
je .tcp
 
jmp s_error
jmp .notsupp
 
.tcp:
.udp:
 
cmp ebx, [edx + 4] ; First, fill in the IP
mov ebx, [edx + 4] ; First, fill in the IP
test ebx, ebx ; If IP is 0, use default
jnz @f
mov ebx, [IP_LIST + 4] ;;;;; FIXME !i!i!i
442,7 → 458,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,\
451,9 → 467,14
mov dword [esp+32], 0
ret
 
.addrinuse:
mov dword[esp+32], -1
mov dword[esp+20], EADDRINUSE
ret
 
 
 
 
;-----------------------------------------------------------------
;
; SOCKET_connect
470,16 → 491,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+20], EOPNOTSUPP
mov dword[esp+32], -1
ret
 
.invalid:
mov dword[esp+20], EINVAL
mov dword[esp+32], -1
ret
 
.af_inet4:
cmp [eax + IP_SOCKET.LocalIP], 0
jne @f
499,7 → 528,7
cmp [eax + SOCKET.Protocol], IP_PROTO_ICMP
je .ip
 
jmp s_error
jmp .notsupp
 
align 4
.udp:
557,18 → 586,15
pop [eax + TCP_SOCKET.ISS]
mov [eax + TCP_SOCKET.timer_keepalive], TCP_time_keep_init
 
 
TCP_sendseqinit eax
 
; mov [ebx + TCP_SOCKET.timer_retransmission], ;; todo: create macro to set retransmission timer
 
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]
575,14 → 601,40
call mutex_unlock
popa
 
push ebx
mov eax, ebx
call TCP_output
pop eax
 
;;; TODO: wait for successfull connection if blocking socket
.block:
test [eax + SOCKET.options], SO_NONBLOCK
jz .loop
 
mov dword[esp+20], EWOULDBLOCK
mov dword[esp+32], -1
ret
 
.loop:
cmp [eax + TCP_SOCKET.t_state], TCPS_CLOSED
je .fail
cmp [eax + TCP_SOCKET.t_state], TCPS_ESTABLISHED
je .established
ja .fail
 
call SOCKET_block
jmp .loop
 
.fail:
mov eax, [eax + SOCKET.errorcode]
mov [esp+20], eax
mov dword[esp+32], -1
ret
 
.established:
mov dword [esp+32], 0
ret
 
 
align 4
.ip:
pusha
619,16 → 671,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
651,10 → 703,24
pop eax
 
mov dword [esp+32], 0
ret
 
.notsupp:
mov dword[esp+20], EOPNOTSUPP
mov dword[esp+32], -1
ret
 
.invalid:
mov dword[esp+20], EINVAL
mov dword[esp+32], -1
ret
 
.already:
mov dword[esp+20], EALREADY
mov dword[esp+32], -1
ret
 
 
;-----------------------------------------------------------------
;
; SOCKET_accept
671,16 → 737,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
688,14 → 754,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
702,11 → 769,26
 
.block:
test [eax + SOCKET.options], SO_NONBLOCK
jnz s_error
jnz .wouldblock
 
call SOCKET_block
jmp .loop
 
.wouldblock:
mov dword[esp+20], EWOULDBLOCK
mov dword[esp+32], -1
ret
 
.invalid:
mov dword[esp+20], EINVAL
mov dword[esp+32], -1
ret
 
.notsupp:
mov dword[esp+20], EOPNOTSUPP
mov dword[esp+32], -1
ret
 
;-----------------------------------------------------------------
;
; SOCKET_close
721,11 → 803,10
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.
 
.socket:
or [eax + SOCKET.options], SO_NONBLOCK ; Mark the socket as non blocking, we dont want it to block any longer!
 
test [eax + SOCKET.state], SS_BLOCKED ; Is the socket still in blocked state?
749,10 → 830,17
 
call TCP_usrclosed
call TCP_output ;;;; Fixme: is this nescessary??
call SOCKET_free
 
ret
 
 
.invalid:
mov dword[esp+20], EINVAL
mov dword[esp+32], -1
ret
 
 
;-----------------------------------------------------------------
;
; SOCKET_receive
770,29 → 858,52
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
 
.loop:
push edi
call [eax + SOCKET.rcv_proc]
pop edi
 
cmp ebx, EWOULDBLOCK
jne .return
 
test edi, MSG_DONTWAIT
jnz .return_err
 
; test [eax + SOCKET.options], SO_NONBLOCK
; jnz .return_err
 
call SOCKET_block
jmp .loop
 
 
.invalid:
push EINVAL
pop ebx
.return_err:
mov eax, -1
.return:
mov [esp+20], ebx
mov [esp+32], eax
ret
 
 
 
 
 
align 4
SOCKET_receive_dgram:
 
DEBUGF DEBUG_NETWORK_VERBOSE, "SOCKET_receive: DGRAM\n"
 
mov ebx, esi
mov edi, edx ; addr to buffer
mov ebx, esi ; bufferlength
 
.loop:
get_from_queue (eax + SOCKET_QUEUE_LOCATION), SOCKET_QUEUE_SIZE, sizeof.socket_queue_entry, .block ; destroys esi and ecx
 
get_from_queue (eax + SOCKET_QUEUE_LOCATION), SOCKET_QUEUE_SIZE, sizeof.socket_queue_entry, .wouldblock ; sets esi only on success.
mov ecx, [esi + socket_queue_entry.data_size]
DEBUGF DEBUG_NETWORK_VERBOSE, "SOCKET_receive: %u bytes data\n", ecx
 
cmp ecx, ebx
cmp ecx, ebx ; If data segment does not fit in applications buffer, abort
ja .too_small
 
push ecx
800,7 → 911,8
mov esi, [esi + socket_queue_entry.data_ptr]
DEBUGF DEBUG_NETWORK_VERBOSE, "SOCKET_receive: Source buffer=%x real addr=%x\n", [esp], esi
 
; copy the data
; copy the data from kernel buffer to application buffer
mov edi, edx ; bufferaddr
shr ecx, 1
jnc .nb
movsb
814,24 → 926,22
rep movsd
.nd:
 
call kernel_free ; remove the packet
pop eax
 
call kernel_free ; free kernel buffer
pop eax ; return number of bytes copied to application
xor ebx, ebx
ret
 
.too_small:
 
DEBUGF DEBUG_NETWORK_VERBOSE, "SOCKET_receive: Buffer too small\n"
.fail:
mov eax, -1
push EMSGSIZE
pop ebx
ret
 
.block:
test [eax + SOCKET.options], SO_NONBLOCK
jnz .fail
.wouldblock:
push EWOULDBLOCK
pop ebx
ret
 
call SOCKET_block
jmp .loop
 
 
align 4
850,56 → 960,42
 
mov [eax + SOCKET.rcv_proc], SOCKET_receive_stream
 
; ... continue to SOCKET_receive_stream
 
align 4
SOCKET_receive_stream:
 
DEBUGF DEBUG_NETWORK_VERBOSE, "SOCKET_receive: STREAM\n"
 
mov ebx, edi
cmp [eax + STREAM_SOCKET.rcv + RING_BUFFER.size], 0
je .wouldblock
 
test edi, MSG_PEEK
jnz .peek
 
mov ecx, esi
mov edi, edx
xor edx, edx
 
test ebx, MSG_DONTWAIT
jnz .dontwait
.loop:
cmp [eax + STREAM_SOCKET.rcv + RING_BUFFER.size], 0
je .block
.dontwait:
test ebx, MSG_PEEK
jnz .peek
 
add eax, STREAM_SOCKET.rcv
call SOCKET_ring_read
call SOCKET_ring_free
call SOCKET_ring_read ; copy data from kernel buffer to application buffer
call SOCKET_ring_free ; free read memory
 
mov eax, ecx ; return number of bytes copied
xor ebx, ebx ; errorcode = 0 (no error)
ret
 
.wouldblock:
push EWOULDBLOCK
pop ebx
ret
 
.peek:
mov eax, [eax + STREAM_SOCKET.rcv + RING_BUFFER.size]
xor ebx, ebx
ret
 
.block:
test [eax + SOCKET.options], SO_NONBLOCK
jnz .return0
 
call SOCKET_block
jmp .loop
 
.return0:
test [eax + SOCKET.options], SS_CANTRCVMORE
jz .ok
 
xor eax, eax
dec eax
ret
 
.ok:
xor eax, eax
ret
 
 
;-----------------------------------------------------------------
;
; SOCKET_send
918,7 → 1014,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
925,7 → 1021,12
 
jmp [eax + SOCKET.snd_proc]
 
.invalid:
mov dword[esp+20], EINVAL
mov dword[esp+32], -1
ret
 
 
align 4
SOCKET_send_udp:
 
934,10 → 1035,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+20], EMSGSIZE ; FIXME: UDP_output should return error codes!
ret
 
 
align 4
SOCKET_send_tcp:
 
949,8 → 1055,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+20], eax
ret
 
 
960,12 → 1070,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+20], EMSGSIZE
ret
 
 
align 4
SOCKET_send_icmp:
 
972,12 → 1087,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+20], EMSGSIZE
ret
 
 
align 4
SOCKET_send_pppoe:
 
986,13 → 1106,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+20], EMSGSIZE
ret
 
 
 
align 4
SOCKET_send_local:
 
1016,7 → 1141,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
1032,7 → 1157,12
 
ret
 
.invalid:
mov dword[esp+32], -1
mov dword[esp+20], EINVAL
ret
 
 
;-----------------------------------------------------------------
;
; SOCKET_get_options
1053,14 → 1183,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
1085,8 → 1215,13
mov dword [esp+32], 0
ret
 
.invalid:
mov dword[esp+32], -1
mov dword[esp+20], EINVAL
ret
 
 
 
;-----------------------------------------------------------------
;
; SOCKET_set_options
1103,19 → 1238,19
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
 
cmp dword [edx+4], SO_BLOCK
je .block
.invalid:
mov dword[esp+32], -1
mov dword[esp+20], EINVAL
ret
 
jmp s_error
 
.bind:
cmp dword [edx+8], 0
je .unbind
1122,11 → 1257,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
1140,23 → 1275,14
mov dword [esp+32], 0 ; success!
ret
 
.block:
cmp dword [edx+8], 0
je .unblock
 
and [eax + SOCKET.options], not SO_NONBLOCK
 
mov dword [esp+32], 0 ; success!
.already:
mov dword[esp+20], EALREADY
mov dword[esp+32], -1
ret
 
.unblock:
or [eax + SOCKET.options], SO_NONBLOCK
 
mov dword [esp+32], 0 ; success!
ret
 
 
 
;-----------------------------------------------------------------
;
; SOCKET_pair
1174,7 → 1300,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
1186,8 → 1312,8
mov ebx, eax
 
call SOCKET_alloc
jz .error
mov [esp+24], edi ; application's ebx
jz .nomem2
mov [esp+20], edi ; application's ebx
 
mov [eax + SOCKET.Domain], AF_LOCAL
mov [eax + SOCKET.Type], SOCK_STREAM
1209,10 → 1335,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
 
 
 
1238,7 → 1367,7
jz .returnall
 
call SOCKET_num_to_ptr
jz s_error
jz .invalid
 
mov esi, eax
mov ecx, SOCKETBUFFSIZE/4
1259,8 → 1388,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
 
 
1342,6 → 1475,11
 
DEBUGF DEBUG_NETWORK_VERBOSE, "SOCKET_check_port: "
 
pusha
mov ecx, socket_mutex
call mutex_lock
popa
 
mov ecx, [eax + SOCKET.Protocol]
mov edx, [eax + IP_SOCKET.LocalIP]
mov esi, net_sockets
1360,10 → 1498,20
cmp [esi + UDP_SOCKET.LocalPort], bx
jne .next_socket
 
pusha
mov ecx, socket_mutex
call mutex_unlock
popa
 
DEBUGF DEBUG_NETWORK_VERBOSE, "local port %x already in use\n", bx ; FIXME: find a way to print big endian values with debugf
ret
 
.port_ok:
pusha
mov ecx, socket_mutex
call mutex_unlock
popa
 
DEBUGF DEBUG_NETWORK_VERBOSE, "local port %x is free\n", bx ; FIXME: find a way to print big endian values with debugf
mov [eax + UDP_SOCKET.LocalPort], bx
or bx, bx ; clear the zero-flag
1659,7 → 1807,7
; Suspends the thread attached to a socket
;
; IN: eax = socket ptr
; OUT: /
; OUT: eax = unchanged
;
;-----------------------------------------------------------------
align 4
1668,6 → 1816,7
DEBUGF DEBUG_NETWORK_VERBOSE, "SOCKET_block: %x\n", eax
 
pushf
push eax
cli
 
; Set the 'socket is blocked' flag
1685,6 → 1834,7
pop edx
 
call change_task
pop eax
popf
 
DEBUGF DEBUG_NETWORK_VERBOSE, "SOCKET_block: continueing\n"
1699,7 → 1849,7
; notify's the owner of a socket that something happened
;
; IN: eax = socket ptr
; OUT: /
; OUT: eax = unchanged
;
;-----------------------------------------------------------------
align 4
1713,8 → 1863,8
test [eax + SOCKET.state], SS_BLOCKED
jnz .unblock
 
test [eax + SOCKET.options], SO_NONBLOCK
jz .error
; test [eax + SOCKET.options], SO_NONBLOCK
; jz .error
 
push eax ecx esi
 
1811,9 → 1961,14
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
call mutex_lock
popa
 
; find first free socket number and use it
mov edi, [last_socket_num]
.next_socket_number:
1872,12 → 2027,23
 
mov [net_sockets + SOCKET.NextPtr], eax
or eax, eax ; used to clear zero flag
 
pusha
mov ecx, socket_mutex
call mutex_unlock
popa
 
.exit:
pop ebx
 
ret
 
.not_yet:
mov dword[esp+20], ENOTCONN
mov dword[esp+32], -1
ret
 
 
;----------------------------------------------------
;
; SOCKET_free
1893,6 → 2059,11
 
DEBUGF DEBUG_NETWORK_VERBOSE, "SOCKET_free: %x\n", eax
 
pusha
mov ecx, socket_mutex
call mutex_lock
popa
 
call SOCKET_check
jz .error
 
1915,6 → 2086,7
mov eax, ebx
.no_tcp:
 
DEBUGF DEBUG_NETWORK_VERBOSE, "SOCKET_free: freeing socket %x\n", eax
push eax ; this will be passed to kernel_free
mov ebx, [eax + SOCKET.NextPtr]
mov eax, [eax + SOCKET.PrevPtr]
1937,6 → 2109,12
DEBUGF DEBUG_NETWORK_VERBOSE, "SOCKET_free: success!\n"
 
.error:
 
pusha
mov ecx, socket_mutex
call mutex_unlock
popa
 
ret
 
;------------------------------------
2005,6 → 2183,11
 
DEBUGF DEBUG_NETWORK_VERBOSE, "SOCKET_num_to_ptr: num=%u ", ecx
 
pusha
mov ecx, socket_mutex
call mutex_lock
popa
 
mov eax, net_sockets
 
.next_socket:
2016,11 → 2199,21
 
test eax, eax
 
pusha
mov ecx, socket_mutex
call mutex_unlock
popa
 
DEBUGF DEBUG_NETWORK_VERBOSE, "ptr=%x\n", eax
ret
 
.error:
DEBUGF DEBUG_NETWORK_ERROR, "SOCKET_nuto_ptr: not found\n", eax
pusha
mov ecx, socket_mutex
call mutex_unlock
popa
 
DEBUGF DEBUG_NETWORK_ERROR, "SOCKET_num_to_ptr: not found\n", eax
ret
 
 
2129,8 → 2322,16
align 4
SOCKET_process_end:
 
pushf
cli ; FIXME
 
DEBUGF DEBUG_NETWORK_VERBOSE, "SOCKET_process_end: %x\n", edx
 
pusha
mov ecx, socket_mutex
call mutex_lock
popa
 
push ebx
mov ebx, net_sockets
 
2148,14 → 2349,45
mov [ebx + SOCKET.PID], 0
mov eax, ebx
mov ebx, [ebx + SOCKET.NextPtr]
 
pusha
call SOCKET_close.socket
mov ecx, socket_mutex
call mutex_unlock
popa
 
pusha
cmp [eax + SOCKET.Domain], AF_INET4
jne .free
 
cmp [eax + SOCKET.Protocol], IP_PROTO_TCP
jne .free
 
call TCP_close
jmp .closed
 
.free:
call SOCKET_free
 
.closed:
popa
 
pusha
mov ecx, socket_mutex
call mutex_lock
popa
 
jmp .next_socket_test
 
.done:
pop ebx
 
pusha
mov ecx, socket_mutex
call mutex_unlock
popa
 
popf
 
ret
 
 
2196,8 → 2428,8
 
DEBUGF DEBUG_NETWORK_VERBOSE, "SOCKET_is_connected: %x\n", eax
 
and [eax + SOCKET.options], not (SS_ISCONNECTING + SS_ISDISCONNECTING + SS_ISCONFIRMING)
or [eax + SOCKET.options], SS_ISCONNECTED
and [eax + SOCKET.state], not (SS_ISCONNECTING + SS_ISDISCONNECTING + SS_ISCONFIRMING)
or [eax + SOCKET.state], SS_ISCONNECTED
 
jmp SOCKET_notify
 
2218,8 → 2450,8
 
DEBUGF DEBUG_NETWORK_VERBOSE, "SOCKET_is_disconnecting: %x\n", eax
 
and [eax + SOCKET.options], not (SS_ISCONNECTING)
or [eax + SOCKET.options], SS_ISDISCONNECTING + SS_CANTRCVMORE + SS_CANTSENDMORE
and [eax + SOCKET.state], not (SS_ISCONNECTING)
or [eax + SOCKET.state], SS_ISDISCONNECTING + SS_CANTRCVMORE + SS_CANTSENDMORE
 
jmp SOCKET_notify
 
2239,8 → 2471,8
 
DEBUGF DEBUG_NETWORK_VERBOSE, "SOCKET_is_disconnected: %x\n", eax
 
and [eax + SOCKET.options], not (SS_ISCONNECTING + SS_ISCONNECTED + SS_ISDISCONNECTING)
or [eax + SOCKET.options], SS_CANTRCVMORE + SS_CANTSENDMORE
and [eax + SOCKET.state], not (SS_ISCONNECTING + SS_ISCONNECTED + SS_ISDISCONNECTING)
or [eax + SOCKET.state], SS_CANTRCVMORE + SS_CANTSENDMORE
 
cmp [eax + SOCKET.Protocol], IP_PROTO_TCP
je .tcp
2272,7 → 2504,7
 
DEBUGF DEBUG_NETWORK_VERBOSE, "SOCKET_cant_recv_more: %x\n", eax
 
or [eax + SOCKET.options], SS_CANTRCVMORE
or [eax + SOCKET.state], SS_CANTRCVMORE
 
call SOCKET_notify
 
2294,9 → 2526,14
 
DEBUGF DEBUG_NETWORK_VERBOSE, "SOCKET_cant_send_more: %x\n", eax
 
or [eax + SOCKET.options], SS_CANTSENDMORE
mov [eax + SOCKET.snd_proc], s_error
or [eax + SOCKET.state], SS_CANTSENDMORE
mov [eax + SOCKET.snd_proc], .notconn
 
call SOCKET_notify
 
ret
 
.notconn:
mov dword[esp+20], ENOTCONN
mov dword[esp+32], -1
ret
/kernel/branches/Kolibri-acpi/network/stack.inc
81,7 → 81,6
SO_USELOOPBACK = 1 shl 8
SO_BINDTODEVICE = 1 shl 9
 
SO_BLOCK = 1 shl 10 ; TO BE REMOVED
SO_NONBLOCK = 1 shl 31
 
; Socket flags for user calls
104,9 → 103,9
SS_RESTARTSYS = 0x0100 ; restart blocked system calls
SS_ISDISCONNECTED = 0x0800 ; socket disconnected from peer
 
SS_ASYNC = 0x0100 ; async i/o notify
SS_ISCONFIRMING = 0x0200 ; deciding to accept connection req
SS_MORETOCOME = 0x0400
SS_ASYNC = 0x1000 ; async i/o notify
SS_ISCONFIRMING = 0x2000 ; deciding to accept connection req
SS_MORETOCOME = 0x4000
 
SS_BLOCKED = 0x8000
 
115,7 → 114,15
MAX_backlog = 20 ; maximum backlog for stream sockets
 
; Error Codes
ENOBUFS = 55
ENOBUFS = 1
EOPNOTSUPP = 4
EWOULDBLOCK = 6
ENOTCONN = 9
EALREADY = 10
EINVAL = 11
EMSGSIZE = 12
ENOMEM = 18
EADDRINUSE = 20
ECONNREFUSED = 61
ECONNRESET = 52
ETIMEDOUT = 60
213,8 → 220,8
 
 
 
uglobal
align 4
uglobal
 
NET_RUNNING dd ?
NET_DRV_LIST rd NET_DEVICES_MAX
450,29 → 457,33
;-----------------------------------------------------------------
align 4
NET_ptr_to_num:
 
call NET_ptr_to_num4
ror edi, 2 ; If -1, stay -1
; valid device numbers have last two bits 0, so do just shr
 
ret
 
align 4
NET_ptr_to_num4: ; Todo, place number in device structure so we only need to verify?
 
push ecx
 
mov ecx, NET_DEVICES_MAX
mov edi, NET_DRV_LIST
 
.loop:
cmp ebx, [edi]
jz .found
je .found
add edi, 4
dec ecx
jnz .loop
 
; repnz scasd could work too if eax is used instead of ebx!
 
or edi, -1
 
pop ecx
ret
 
.found:
sub edi, NET_DRV_LIST
shr edi, 2
 
pop ecx
ret
 
/kernel/branches/Kolibri-acpi/network/tcp.inc
127,8 → 127,9
 
ends
 
uglobal
align 4
uglobal
 
TCP_segments_tx rd NET_DEVICES_MAX
TCP_segments_rx rd NET_DEVICES_MAX
TCP_segments_missed rd NET_DEVICES_MAX
136,7 → 137,7
; TCP_bytes_rx rq NET_DEVICES_MAX
; TCP_bytes_tx rq NET_DEVICES_MAX
TCP_sequence_num dd ?
TCP_queue rd TCP_QUEUE_SIZE*sizeof.TCP_queue_entry/4
TCP_queue rd (TCP_QUEUE_SIZE*sizeof.TCP_queue_entry + sizeof.queue)/4
TCP_input_event dd ?
endg
 
163,6 → 164,10
movi ebx, 1
mov ecx, TCP_process_input
call new_sys_threads
test eax, eax
jns @f
DEBUGF DEBUG_NETWORK_ERROR,'K : cannot create kernel thread for TCP, error %d\n', eax
@@:
 
}
 
/kernel/branches/Kolibri-acpi/network/tcp_input.inc
50,6 → 50,9
 
add esp, sizeof.TCP_queue_entry
 
call NET_ptr_to_num4
inc [TCP_segments_rx + edi]
 
xor edx, edx
mov eax, [TCP_input_event]
mov ebx, [eax + EVENT.id]
62,7 → 65,8
popf
DEBUGF DEBUG_NETWORK_VERBOSE, "TCP incoming queue is full, discarding packet!\n"
 
inc [TCP_segments_missed] ; FIXME: use correct interface
call NET_ptr_to_num4
inc [TCP_segments_missed + edi]
 
add esp, sizeof.TCP_queue_entry - 8
call kernel_free
146,6 → 150,11
; (IP Packet TCP Source Port = remote Port) OR (remote Port = 0)
 
.findpcb:
pusha
mov ecx, socket_mutex
call mutex_lock
popa
 
mov ebx, net_sockets
mov si, [edx + TCP_header.DestinationPort]
 
152,7 → 161,7
.socket_loop:
mov ebx, [ebx + SOCKET.NextPtr]
or ebx, ebx
jz .respond_seg_reset
jz .no_socket ;respond_seg_reset
 
cmp [ebx + SOCKET.Domain], AF_INET4
jne .socket_loop
176,13 → 185,13
test ax, ax
jnz .socket_loop
.found_socket: ; ebx now contains the socketpointer
pusha
mov ecx, socket_mutex
call mutex_unlock
popa
 
DEBUGF DEBUG_NETWORK_VERBOSE, "TCP_input: socket ptr=%x state=%u flags=%x\n", ebx, [ebx + TCP_SOCKET.t_state], [edx + TCP_header.Flags]:2
 
;-------------
; update stats
 
inc [TCP_segments_rx] ; FIXME: correct interface?
 
;----------------------------
; Check if socket isnt closed
 
1161,10 → 1170,18
.ack_la:
jnc .ack_processed
 
push ebx
lea ecx, [ebx + SOCKET.mutex]
call mutex_unlock
pop ebx
 
push ebx
mov eax, ebx
call TCP_disconnect
jmp .drop
pop ebx
 
jmp .destroy_new_socket
 
.ack_tw:
mov [ebx + TCP_SOCKET.timer_timed_wait], 2 * TCP_time_MSL
or [ebx + TCP_SOCKET.timer_flags], timer_flag_wait
1223,7 → 1240,10
 
and [ebx + TCP_SOCKET.temp_bits], not TCP_BIT_DROPSOCKET
 
;;; call SOCKET_notify_owner
pusha
mov eax, ebx
call SOCKET_notify
popa
 
jmp .trim_then_step6
 
1298,7 → 1318,10
;;; TODO: update stats
 
; set socket state to connected
mov [ebx + SOCKET.state], SS_ISCONNECTED
push eax
mov eax, ebx
call SOCKET_is_connected
pop eax
mov [ebx + TCP_SOCKET.t_state], TCPS_ESTABLISHED
 
; Do window scaling on this connection ?
1620,6 → 1643,13
pop ebx
jmp .destroy_new_socket
 
.no_socket:
 
pusha
mov ecx, socket_mutex
call mutex_unlock
popa
 
.respond_seg_reset:
test [edx + TCP_header.Flags], TH_RST
jnz .drop_no_socket
/kernel/branches/Kolibri-acpi/network/tcp_output.inc
35,6 → 35,8
call mutex_lock
pop eax
 
DEBUGF DEBUG_NETWORK_VERBOSE, "TCP_output: socket locked\n"
 
; We'll detect the length of the data to be transmitted, and flags to be used
; If there is some data, or any critical controls to send (SYN / RST), then transmit
; Otherwise, investigate further
216,6 → 218,7
mov ebx, TCP_max_win
shl ebx, cl
pop ecx
 
cmp ebx, ecx
jb @f
mov ebx, ecx
549,7 → 552,8
pop ecx
pop eax
 
inc [TCP_segments_tx] ; FIXME: correct interface?
call NET_ptr_to_num4
inc [TCP_segments_tx + edi]
 
; update advertised receive window
test ecx, ecx
570,6 → 574,8
;--------------
; unlock socket
 
DEBUGF DEBUG_NETWORK_VERBOSE, "TCP_send: unlocking socket 0x%x\n", eax
 
push eax
lea ecx, [eax + SOCKET.mutex]
call mutex_unlock
606,7 → 612,8
 
 
.send_error:
add esp, 8
add esp, 4
pop eax
 
lea ecx, [eax + SOCKET.mutex]
call mutex_unlock
/kernel/branches/Kolibri-acpi/network/tcp_subr.inc
164,7 → 164,7
 
;;; TODO: check if error code is "Connection timed out' and handle accordingly
 
mov [eax + SOCKET.errorcode], ebx
; mov [eax + SOCKET.errorcode], ebx
 
 
 
302,6 → 302,11
; And send the segment
 
call [ebx + NET_DEVICE.transmit]
test eax, eax
jnz @f
call NET_ptr_to_num4
inc [TCP_segments_tx + edi]
@@:
ret
 
.error:
378,6 → 383,11
; And send the segment
 
call [ebx + NET_DEVICE.transmit]
test eax, eax
jnz @f
call NET_ptr_to_num4
inc [TCP_segments_tx + edi]
@@:
ret
 
.error:
/kernel/branches/Kolibri-acpi/network/tcp_usreq.inc
97,6 → 97,9
 
call SOCKET_is_disconnecting
call TCP_usrclosed
 
push eax
call TCP_output
pop eax
 
ret
/kernel/branches/Kolibri-acpi/network/udp.inc
27,10 → 27,12
ends
 
 
uglobal
align 4
uglobal
 
UDP_PACKETS_TX rd NET_DEVICES_MAX
UDP_PACKETS_RX rd NET_DEVICES_MAX
 
endg
 
 
114,6 → 116,7
;
;-----------------------------------------------------------------
align 4
diff16 "UDP packetgfgfgfgfs", 0, $
UDP_input:
 
DEBUGF DEBUG_NETWORK_VERBOSE, "UDP_input: size=%u\n", ecx
139,6 → 142,11
; IP Packet UDP Destination Port = local Port
; IP Packet SA = Remote IP
 
pusha
mov ecx, socket_mutex
call mutex_lock
popa
 
mov cx, [esi + UDP_header.SourcePort]
mov dx, [esi + UDP_header.DestinationPort]
mov edi, [edi + 4] ; ipv4 source address
147,7 → 155,7
.next_socket:
mov eax, [eax + SOCKET.NextPtr]
or eax, eax
jz .dump
jz .dump_
 
cmp [eax + SOCKET.Domain], AF_INET4
jne .next_socket
160,6 → 168,11
 
DEBUGF DEBUG_NETWORK_VERBOSE, "UDP_input: socket=%x\n", eax
 
pusha
mov ecx, socket_mutex
call mutex_unlock
popa
 
;;; TODO: when packet is processed, check more sockets!
 
; cmp [eax + IP_SOCKET.RemoteIP], 0xffffffff
182,7 → 195,8
popa
 
.updatesock:
inc [UDP_PACKETS_RX] ; Fixme: correct interface?
call NET_ptr_to_num4
inc [UDP_PACKETS_RX + edi]
 
movzx ecx, [esi + UDP_header.Length]
sub ecx, sizeof.UDP_header
202,7 → 216,17
 
jmp .updatesock
 
.dump_:
 
pusha
mov ecx, socket_mutex
call mutex_unlock
popa
 
DEBUGF DEBUG_NETWORK_VERBOSE, "UDP_input: no socket found\n"
 
jmp .dump
 
.checksum_mismatch:
DEBUGF DEBUG_NETWORK_VERBOSE, "UDP_input: checksum mismatch\n"
 
274,7 → 298,8
call [ebx + NET_DEVICE.transmit]
test eax, eax
jnz @f
inc [UDP_PACKETS_TX] ; FIXME: correct device?
call NET_ptr_to_num4
inc [UDP_PACKETS_TX + edi]
@@:
 
ret