Subversion Repositories Kolibri OS

Compare Revisions

Regard whitespace Rev 5984 → Rev 5983

/kernel/branches/Kolibri-acpi/network/IPv4.inc
16,7 → 16,7
;; ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 
$Revision: 5842 $
$Revision: 5584 $
 
IPv4_MAX_FRAGMENTS = 64
IPv4_MAX_ROUTES = 64
215,6 → 215,7
; It will also re-construct fragmented packets
;
; IN: Pointer to buffer in [esp]
; size of buffer in [esp+4]
; pointer to device struct in ebx
; pointer to IPv4 header in edx
; size of IPv4 packet in ecx
222,7 → 223,7
;
;-----------------------------------------------------------------
align 4
IPv4_input:
IPv4_input: ; TODO: add IPv4 raw sockets support
 
DEBUGF DEBUG_NETWORK_VERBOSE, "IPv4_input: packet from %u.%u.%u.%u ",\
[edx + IPv4_header.SourceAddress + 0]:1,[edx + IPv4_header.SourceAddress + 1]:1,\
231,10 → 232,6
[edx + IPv4_header.DestinationAddress + 0]:1,[edx + IPv4_header.DestinationAddress + 1]:1,\
[edx + IPv4_header.DestinationAddress + 2]:1,[edx + IPv4_header.DestinationAddress + 3]:1
 
call NET_ptr_to_num4
cmp edi, -1
je .invalid_device
 
;-------------------------------
; re-calculate the checksum
 
243,32 → 240,40
 
DEBUGF DEBUG_NETWORK_VERBOSE, "IPv4_input: Checksum ok\n"
 
;--------------------------------
; Check if destination IP matches
;-----------------------------------
; Check if destination IP is correct
 
; local ip (Using RFC1122 strong end system model)
call NET_ptr_to_num4
 
; check if it matches local ip (Using RFC1122 strong end system model)
 
mov eax, [edx + IPv4_header.DestinationAddress]
cmp eax, [IP_LIST + edi]
je .ip_ok
 
; network layer broadcast
; check for broadcast (IP or (not SUBNET))
 
cmp eax, [BROADCAST_LIST + edi]
je .ip_ok
 
; physical layer broadcast (255.255.255.255)
; or a special broadcast (255.255.255.255)
 
cmp eax, 0xffffffff
je .ip_ok
 
; multicast (224.0.0.0/4 = 224.0.0.0 to 239.255.255.255)
; maybe it's a multicast (224.0.0.0/4)
 
and eax, 0x0fffffff
cmp eax, 224
je .ip_ok
 
; maybe we just dont have an IP yet and should accept everything on the IP level
 
cmp [IP_LIST + edi], 0
je .ip_ok
 
; or it's just not meant for us.. :(
 
DEBUGF DEBUG_NETWORK_VERBOSE, "IPv4_input: Destination address does not match!\n"
jmp .dump
 
300,6 → 305,7
xchg cl, ch ;
sub ecx, esi ;
 
lea edi, [edx + IPv4_header.SourceAddress] ; make edi ptr to source and dest IPv4 address
mov al, [edx + IPv4_header.Protocol]
add esi, edx ; make esi ptr to data
 
312,64 → 318,15
cmp al, IP_PROTO_ICMP
je ICMP_input
 
;-------------------------------
; Look for a matching RAW socket
pusha
mov ecx, socket_mutex
call mutex_lock
popa
 
add ecx, esi
sub ecx, edx
mov esi, edx
movzx edx, al
mov eax, net_sockets
.next_socket:
mov eax, [eax + SOCKET.NextPtr]
or eax, eax
jz .dump_unlock
 
cmp [eax + SOCKET.Domain], AF_INET4
jne .next_socket
 
cmp [eax + SOCKET.Protocol], edx
jne .next_socket
 
pusha
mov ecx, socket_mutex
call mutex_unlock
popa
 
DEBUGF DEBUG_NETWORK_VERBOSE, "IPv4_input: found matching RAW socket: 0x%x\n", eax
 
pusha
lea ecx, [eax + SOCKET.mutex]
call mutex_lock
popa
 
jmp SOCKET_input
 
.dump_unlock:
 
pusha
mov ecx, socket_mutex
call mutex_unlock
popa
 
DEBUGF DEBUG_NETWORK_VERBOSE, "IPv4_input: unknown protocol %u\n", al
 
.dump:
DEBUGF DEBUG_NETWORK_VERBOSE, "IPv4_input: dumping\n"
inc [IPv4_packets_dumped + edi]
inc [IPv4_packets_dumped] ; FIXME: use correct interface
call NET_BUFF_free
ret
 
.invalid_device:
DEBUGF DEBUG_NETWORK_ERROR, "IPv4_input: packet originated from invalid device\n"
call NET_BUFF_free
ret
 
 
;---------------------------
; Fragmented packet handler
 
611,12 → 568,11
;
; IPv4_output
;
; IN: al = protocol
; ah = TTL
; IN: eax = Destination IP
; ebx = device ptr (or 0 to let IP layer decide)
; ecx = data length
; edx = Source IP
; edi = Destination IP
; di = TTL shl 8 + protocol
;
; OUT: eax = pointer to buffer start / 0 on error
; ebx = device ptr (send packet through this device)
633,8 → 589,7
cmp ecx, 65500 ; Max IPv4 packet size
ja .too_large
 
push ecx ax edi
mov eax, edi
push ecx di eax
call IPv4_route ; outputs device number in edi, dest ip in eax, source IP in edx
push edx
test edi, edi
687,10 → 642,7
 
.arp_error:
DEBUGF DEBUG_NETWORK_ERROR, "IPv4_output: ARP error=%x\n", eax
add esp, 4
pop eax
DEBUGF DEBUG_NETWORK_ERROR, "IPv4_output: ip=0x%x\n", eax
add esp, 4+2
add esp, 3*4+2
xor eax, eax
ret
 
726,6 → 678,9
 
DEBUGF 1,"IPv4_output_raw: size=%u ptr=%x socket=%x\n", ecx, esi, eax
 
cmp ecx, 1480 ;;;;; FIXME
ja .too_large
 
sub esp, 8
push esi eax
 
752,7 → 707,7
mov dword[esp+4+4+4], eax
 
pop eax esi
;; TODO: check socket options if we should add header, or just compute checksum
;; todo: check socket options if we should add header, or just compute checksum
 
push edi ecx
rep movsb
779,14 → 734,11
ret
 
.error:
add esp, 6+8+4+4
mov ebx, ENOBUFS ; FIXME: NOBUFS or MSGSIZE error
or eax, -1
ret
 
add esp, 6
.arp_error:
add esp, 8+4+4
mov ebx, ENOTCONN
.too_large:
DEBUGF DEBUG_NETWORK_ERROR, "IPv4_output_raw: Failed\n"
or eax, -1
ret
 
794,122 → 746,119
;--------------------------------------------------------
;
;
; IN: [esp] = pointer to buffer containing ipv4 packet to be fragmented
; edi = pointer to ip header in that buffer
; ebx = device ptr
; IN: dword [esp] = pointer to buffer containing ipv4 packet to be fragmented
; esi = pointer to ip header in that buffer
; ecx = max size of fragments
;
; OUT: /
;
;--------------------------------------------------------
proc IPv4_fragment stdcall buffer
 
locals
offset dd ?
headerlength dd ?
headerptr dd ?
dataptr dd ?
remaining dd ?
segmentsize dd ?
endl
align 4
IPv4_fragment:
 
DEBUGF DEBUG_NETWORK_VERBOSE, "IPv4_fragment\n"
 
; We must be able to put at least 8 bytes per segment
movzx eax, byte[edi] ; IHL
and eax, 0xf
shl eax, 2
mov [headerlength], eax
add eax, 8
mov ecx, [ebx + NET_DEVICE.mtu]
and ecx, not 11b
cmp ecx, eax
jb .fail
and ecx, not 111b ; align 4
 
mov [edi + IPv4_header.HeaderChecksum], 0
cmp ecx, sizeof.IPv4_header + 8 ; must be able to put at least 8 bytes
jb .err2
 
mov [segmentsize], ecx
mov [headerptr], edi
movzx ecx, [edi + IPv4_header.TotalLength]
xchg cl, ch
sub ecx, [headerlength]
mov [remaining], ecx
mov [offset], 0
push esi ecx
mov eax, [esi + IPv4_header.DestinationAddress]
call ARP_IP_to_MAC
pop ecx esi
cmp eax, -1
jz .err2
 
add edi, [headerlength]
mov [dataptr], edi
push ebx
push ax
 
.loop:
mov ebx, [NET_DRV_LIST]
lea eax, [ebx + ETH_DEVICE.mac]
push eax
 
 
push esi ; ptr to ip header
sub ecx, sizeof.IPv4_header ; substract header size
push ecx ; max data size
push dword 0 ; offset
 
.new_fragment:
DEBUGF DEBUG_NETWORK_VERBOSE, "Ipv4_fragment: new fragment"
 
mov ecx, [segmentsize]
cmp ecx, [remaining]
jbe @f
mov ecx, [remaining]
@@:
 
mov ax, ETHER_PROTO_IPv4
mov edx, [esp]
add edx, [edx + NET_BUFF.offset]
; add edx, ETH_header.DstMAC ; = 0
lea ebx, [esp + 4*4]
call ETH_output
jz .fail
jz .err
 
push edi
mov edx, ecx
 
; copy header
mov esi, [headerptr]
mov ecx, [headerlength]
shr ecx, 2
mov esi, [esp + 2*4]
mov ecx, 5 ; 5 dwords: TODO: use IHL field of the header!
rep movsd
 
; copy data
mov esi, [dataptr]
add esi, [offset]
mov ecx, edx
sub ecx, [headerlength]
shr ecx, 2
rep movsd
pop edi
mov esi, [esp + 2*4]
add esi, sizeof.IPv4_header
add esi, [esp] ; offset
 
mov ecx, [esp + 1*4]
DEBUGF DEBUG_NETWORK_VERBOSE, "IPv4_fragment: copying %u bytes\n", ecx
rep movsb
 
; now, correct header
; packet length
mov ax, dx
xchg al, ah
mov [edi + IPv4_header.TotalLength], ax
mov ecx, [esp + 1*4]
add ecx, sizeof.IPv4_header
xchg cl, ch
mov [edi + IPv4_header.TotalLength], cx
 
; offset
mov eax, [offset]
xchg al, ah
mov ecx, [esp] ; offset
xchg cl, ch
 
sub edx, [headerlength]
sub [remaining], edx
je @f
jb .fail
or ah, 1 shl 2 ; more fragments
add [offset], edx
@@:
mov [edi + IPv4_header.FlagsAndFragmentOffset], ax
; cmp dword[esp + 4*4], 0 ; last fragment?;<<<<<<
; je .last_fragment
or cx, 1 shl 2 ; more fragments
; .last_fragment:
mov [edi + IPv4_header.FlagsAndFragmentOffset], cx
 
; Send the fragment
mov [edi + IPv4_header.HeaderChecksum], 0
 
;<<<<<<<<<<<<<<<<<<<<<<<<<<<<< send the packet
mov ecx, [esp + 1*4]
 
push edx eax
IPv4_checksum edi
 
call [ebx + NET_DEVICE.transmit]
;<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
 
cmp [remaining], 0
jne .loop
mov ecx, [esp+4]
add [esp], ecx
 
call NET_BUFF_free
ret
mov ecx, [esp+3*4+6+4] ; ptr to begin of buff
add ecx, [esp+3*4+6+4+4] ; buff size
sub ecx, [esp+2*4] ; ptr to ip header
add ecx, [esp] ; offset
 
.fail:
DEBUGF DEBUG_NETWORK_VERBOSE, "Ipv4_fragment: %u bytes remaining\n", ecx
 
cmp ecx, [esp+1*4]
jae .new_fragment
 
mov [esp+4], ecx ; set fragment size to remaining packet size
jmp .new_fragment
 
.err:
DEBUGF DEBUG_NETWORK_ERROR, "Ipv4_fragment: failed\n"
.done:
add esp, 12 + 4 + 6
.err2:
DEBUGF DEBUG_NETWORK_VERBOSE, "Ipv4_fragment: dumping\n"
call NET_BUFF_free
ret
 
endp
 
 
 
;---------------------------------------------------------------------------
;
; IPv4_route
1024,6 → 973,11
pushd [edx + 4]
pop [eax + IP_SOCKET.RemoteIP]
 
; Set up data receiving queue
push eax
init_queue (eax + SOCKET_QUEUE_LOCATION)
pop eax
 
lea ecx, [eax + SOCKET.mutex]
call mutex_unlock
 
/kernel/branches/Kolibri-acpi/network/tcp_output.inc
16,15 → 16,14
 
$Revision: 5584 $
 
;-----------------------------------------------------------------;
; ;
; TCP_output ;
; ;
; IN: eax = socket pointer ;
; ;
; OUT: eax = 0 on success/errorcode ;
; ;
;-----------------------------------------------------------------;
;-----------------------------------------------------------------
;
; TCP_output
;
; IN: eax = socket pointer
; OUT: eax = 0 on success/errorcode
;
;-----------------------------------------------------------------
align 4
proc TCP_output
 
504,11 → 503,10
; Create the IP packet
 
mov ecx, esi
mov edx, [eax + IP_SOCKET.LocalIP] ; source ip
mov ebx, [eax + IP_SOCKET.device]
mov edx, [eax + IP_SOCKET.LocalIP] ; source ip
mov edi, [eax + IP_SOCKET.RemoteIP] ; dest ip
mov al, [eax + IP_SOCKET.ttl]
mov ah, IP_PROTO_TCP
mov eax, [eax + IP_SOCKET.RemoteIP] ; dest ip
mov di, IP_PROTO_TCP shl 8 + 128
call IPv4_output
jz .ip_error
 
/kernel/branches/Kolibri-acpi/network/tcp_subr.inc
104,17 → 104,18
}
 
 
;-----------------------------------------------------------------;
; ;
; TCP_pull_out_of_band ;
; ;
; IN: eax = ? ;
; ebx = socket ptr ;
; edx = tcp packet ptr ;
; ;
; OUT: / ;
; ;
;-----------------------------------------------------------------;
;---------------------------
;
; TCP_pull_out_of_band
;
; IN: eax =
; ebx = socket ptr
; edx = tcp packet ptr
;
; OUT: /
;
;---------------------------
 
align 4
TCP_pull_out_of_band:
 
126,16 → 127,21
 
 
 
;-----------------------------------------------------------------;
; ;
; TCP_drop ;
; ;
; IN: eax = socket ptr ;
; ebx = error number ;
; ;
; OUT: eax = socket ptr ;
; ;
;-----------------------------------------------------------------;
 
 
 
 
 
;-------------------------
;
; TCP_drop
;
; IN: eax = socket ptr
; ebx = error number
;
; OUT: eax = socket ptr
;
;-------------------------
align 4
TCP_drop: ; FIXME CHECKME TODO
 
165,15 → 171,14
 
 
 
;-----------------------------------------------------------------;
; ;
; TCP_disconnect ;
; ;
; IN: eax = socket ptr ;
; ;
; OUT: eax = socket ptr / 0 ;
; ;
;-----------------------------------------------------------------;
;-------------------------
;
; TCP_disconnect
;
; IN: eax = socket ptr
; OUT: eax = socket ptr / 0
;
;-------------------------
align 4
TCP_disconnect:
 
193,18 → 198,18
call TCP_output
pop eax
@@:
 
ret
 
 
;-----------------------------------------------------------------;
; ;
; TCP_close ;
; ;
; IN: eax = socket ptr ;
; ;
; OUT: / ;
; ;
;-----------------------------------------------------------------;
;-------------------------
;
; TCP_close
;
; IN: eax = socket ptr
; OUT: /
;
;-------------------------
align 4
TCP_close:
 
217,19 → 222,21
call SOCKET_free
 
xor eax, eax
 
ret
 
 
 
;-----------------------------------------------------------------;
; ;
; TCP_outflags ;
; ;
; IN: eax = socket ptr ;
; ;
; OUT: edx = flags ;
; ;
;-----------------------------------------------------------------;
 
;-------------------------
;
; TCP_outflags
;
; IN: eax = socket ptr
;
; OUT: edx = flags
;
;-------------------------
align 4
TCP_outflags:
 
259,16 → 266,16
 
 
 
;-----------------------------------------------------------------;
; ;
; TCP_respond: Fast way to send an ACK/RST/keepalive segment. ;
; ;
; IN: ebx = socket ptr ;
; cl = flags ;
; ;
; OUT: / ;
; ;
;-----------------------------------------------------------------;
;---------------------------------------
;
; The fast way to send an ACK/RST/keepalive segment
;
; TCP_respond
;
; IN: ebx = socket ptr
; cl = flags
;
;--------------------------------------
align 4
TCP_respond:
 
278,12 → 285,11
; Create the IP packet
 
push cx ebx
mov eax, [ebx + IP_SOCKET.RemoteIP]
mov edx, [ebx + IP_SOCKET.LocalIP]
mov edi, [ebx + IP_SOCKET.RemoteIP]
mov al, [ebx + IP_SOCKET.ttl]
mov ah, IP_PROTO_TCP
mov ebx, [ebx + IP_SOCKET.device]
mov ecx, sizeof.TCP_header
mov ebx, [ebx + IP_SOCKET.device]
mov di, IP_PROTO_TCP shl 8 + 128
call IPv4_output
jz .error
pop esi cx
341,18 → 347,19
ret
 
 
;-----------------------------------------------------------------;
; ;
; TCP_respond_segment ;
; ;
; IN: ebx = device ptr ;
; edx = segment ptr (a previously received segment) ;
; edi = ptr to IPv4 header ;
; cl = flags ;
; ;
; OUT: / ;
; ;
;-----------------------------------------------------------------;
 
 
 
 
 
 
;-------------------------
; TCP_respond_segment:
;
; IN: edx = segment ptr (a previously received segment)
; edi = ptr to dest and src IPv4 addresses
; cl = flags
 
align 4
TCP_respond_segment:
 
362,10 → 369,11
; Create the IP packet
 
push cx edx
mov edx, [edi + IPv4_header.DestinationAddress]
mov edi, [edi + IPv4_header.SourceAddress]
mov edx, [edi + 4]
mov eax, [edi]
mov ecx, sizeof.TCP_header
mov ax, IP_PROTO_TCP shl 8 + 128
mov di, IP_PROTO_TCP shl 8 + 128
xor ebx, ebx ;;; fixme
call IPv4_output
jz .error
pop esi cx
446,11 → 454,7
.done:
}
 
;-----------------------------------------------------------------;
; ;
; TCP_set_persist ;
; ;
;-----------------------------------------------------------------;
 
align 4
TCP_set_persist:
 
487,20 → 491,13
 
 
 
;-----------------------------------------------------------------;
; ;
; TCP_xmit_timer: Calculate new smoothed RTT. ;
; ;
; IN: eax = rtt ;
; ebx = socket ptr ;
; ;
; OUT: / ;
; ;
;-----------------------------------------------------------------;
; eax = rtt
; ebx = socket ptr
 
align 4
TCP_xmit_timer:
 
DEBUGF DEBUG_NETWORK_VERBOSE, "TCP_xmit_timer: socket=0x%x rtt=%d0ms\n", ebx, eax
DEBUGF DEBUG_NETWORK_VERBOSE, "TCP_xmit_timer: socket=%x rtt=%d0ms\n", ebx, eax
 
;TODO: update stats
 
549,6 → 546,7
 
 
.no_rtt_yet:
 
push ecx
mov ecx, eax
shl ecx, TCP_RTT_SHIFT
561,16 → 559,10
ret
 
 
;-----------------------------------------------------------------;
; ;
; TCP_mss: Update maximum segment size ;
; ;
; IN: eax = max segment size ;
; ebx = socket ptr ;
; ;
; OUT: / ;
; ;
;-----------------------------------------------------------------;
 
 
; eax = max segment size
; ebx = socket ptr
align 4
TCP_mss:
 
585,20 → 577,13
 
 
 
;-----------------------------------------------------------------;
; ;
; TCP_reassemble ;
; ;
; IN: ebx = socket ptr ;
; edx = segment ptr ;
; ;
; OUT: / ;
; ;
;-----------------------------------------------------------------;
 
; ebx = socket ptr
; edx = segment ptr
align 4
TCP_reassemble:
 
;;;;; TODO
 
 
ret
 
/kernel/branches/Kolibri-acpi/network/icmp.inc
133,9 → 133,8
; IN: Pointer to buffer in [esp]
; ebx = pointer to device struct
; ecx = ICMP Packet size
; edx = ptr to IPv4 header
; esi = ptr to ICMP Packet data
; edi = interface number*4
; edi = ptr to ipv4 source and dest address
;
; OUT: /
;
145,13 → 144,8
 
DEBUGF DEBUG_NETWORK_VERBOSE, "ICMP_input\n"
 
; Dump all multicasts and broadcasts
mov eax, [IP_LIST + edi]
cmp eax, [edx + IPv4_header.DestinationAddress]
jne .dump
 
; Check the checksum
push esi ecx edx
push esi ecx
push [esi + ICMP_header.Checksum]
mov [esi + ICMP_header.Checksum], 0
xor edx, edx
159,11 → 153,17
call checksum_2
pop si
cmp dx, si
pop edx ecx esi
pop ecx esi
jne .checksum_mismatch
 
DEBUGF DEBUG_NETWORK_VERBOSE, "ICMP_input: Checksum OK\n"
 
; Ualidate device ptr
mov eax, edi
call NET_ptr_to_num4
cmp edi, -1
je .dump
 
; Update stats
inc [ICMP_PACKETS_RX + edi]
 
177,10 → 177,10
call mutex_lock
popa
 
add ecx, esi
sub ecx, edx
mov esi, edx
mov edx, [eax] ; ipv4 source address
mov eax, net_sockets
.try_more:
; mov , [esi + ICMP_header.Identifier]
.next_socket:
mov eax, [eax + SOCKET.NextPtr]
or eax, eax
192,6 → 192,12
cmp [eax + SOCKET.Protocol], IP_PROTO_ICMP
jne .next_socket
 
cmp [eax + IP_SOCKET.RemoteIP], edx
jne .next_socket
 
; cmp [eax + ICMP_SOCKET.Identifier],
; jne .next_socket
 
pusha
mov ecx, socket_mutex
call mutex_unlock
370,7 → 376,7
;
; IN: eax = socket ptr
; ecx = data length
; edx = data pointer
; esi = data offset
;
;-----------------------------------------------------------------
align 4
379,13 → 385,13
DEBUGF DEBUG_NETWORK_VERBOSE, "Creating ICMP Packet for socket %x, data ptr=%x\n", eax, edx
 
push edx
 
mov di, IP_PROTO_ICMP SHL 8 + 128 ; TTL
mov edx, [eax + IP_SOCKET.LocalIP]
mov ebx, [eax + IP_SOCKET.device]
mov edx, [eax + IP_SOCKET.LocalIP]
mov edi, [eax + IP_SOCKET.RemoteIP]
mov al, [eax + IP_SOCKET.ttl]
mov ah, IP_PROTO_ICMP
mov eax, [eax + IP_SOCKET.RemoteIP]
call IPv4_output
jz .fail
jz .exit
 
pop esi
push eax
411,12 → 417,8
inc [ICMP_PACKETS_TX + edi]
@@:
ret
 
.fail:
pop edx
.exit:
DEBUGF DEBUG_NETWORK_ERROR, "Creating ICMP Packet failed\n"
or eax, -1
mov ebx, EMSGSIZE ;;; FIXME
ret
 
 
/kernel/branches/Kolibri-acpi/network/socket.inc
27,15 → 27,15
 
PID dd ? ; process ID
TID dd ? ; thread ID
Domain dd ? ; INET4/INET6/LOCAL/..
Domain dd ? ; INET/LOCAL/..
Type dd ? ; RAW/STREAM/DGRAM
Protocol dd ? ; UDP/TCP/ARP/ICMP
Protocol dd ? ; ICMP/IPv4/ARP/TCP/UDP
errorcode dd ?
device dd ? ; device pointer, paired socket pointer if it's a local socket
device dd ? ; driver pointer, socket pointer if it's an LOCAL socket
 
options dd ?
state dd ?
backlog dw ? ; number of incoming connections that can be queued
backlog dw ? ; how many incoming connections that can be queued
 
snd_proc dd ?
rcv_proc dd ?
47,8 → 47,6
 
LocalIP rd 4 ; network byte order
RemoteIP rd 4 ; network byte order
ttl db ?
rb 3 ; align
 
ends
 
147,11 → 145,19
 
struct UDP_SOCKET IP_SOCKET
 
LocalPort dw ? ; in network byte order
RemotePort dw ? ; in network byte order
LocalPort dw ? ; network byte order
RemotePort dw ? ; network byte order
 
ends
 
 
struct ICMP_SOCKET IP_SOCKET
 
Identifier dw ?
 
ends
 
 
struct RING_BUFFER
 
mutex MUTEX
178,15 → 184,7
 
ends
 
struct socket_options
 
level dd ?
optname dd ?
optlen dd ?
optval dd ?
 
ends
 
SOCKETBUFFSIZE = 4096 ; in bytes
 
SOCKET_QUEUE_SIZE = 10 ; maximum number of incoming packets queued for 1 socket
198,7 → 196,7
 
net_sockets rd 4
last_socket_num dd ?
last_UDP_port dw ? ; last used ephemeral port
last_UDP_port dw ? ; These values give the number of the last used ephemeral port
last_TCP_port dw ? ;
socket_mutex MUTEX
 
205,11 → 203,11
endg
 
 
;-----------------------------------------------------------------;
; ;
; SOCKET_init ;
; ;
;-----------------------------------------------------------------;
;-----------------------------------------------------------------
;
; SOCKET_init
;
;-----------------------------------------------------------------
macro SOCKET_init {
 
xor eax, eax
240,11 → 238,11
 
}
 
;-----------------------------------------------------------------;
; ;
; Sockets API (system function 75) ;
; ;
;-----------------------------------------------------------------;
;-----------------------------------------------------------------
;
; Socket API (function 74)
;
;-----------------------------------------------------------------
align 4
sys_socket:
 
277,19 → 275,16
 
ret
 
;-----------------------------------------------------------------;
; ;
; SOCKET_open: Create a new socket. ;
; ;
; IN: ecx = domain ;
; edx = type ;
; esi = protocol ;
; ;
; OUT: eax = socket number ;
; eax = -1 on error ;
; ebx = errorcode on error ;
; ;
;-----------------------------------------------------------------;
;-----------------------------------------------------------------
;
; SOCKET_open
;
; IN: domain in ecx
; type in edx
; protocol in esi
; OUT: eax is socket num, -1 on error
;
;-----------------------------------------------------------------
align 4
SOCKET_open:
 
318,8 → 313,6
cmp ecx, AF_INET4
jne .no_inet4
 
mov [eax + IP_SOCKET.ttl], 128
 
cmp edx, SOCK_DGRAM
je .udp
 
361,10 → 354,6
 
align 4
.udp:
push eax
init_queue (eax + SOCKET_QUEUE_LOCATION) ; Set up data receiving queue
pop eax
 
mov [eax + SOCKET.Protocol], IP_PROTO_UDP
mov [eax + SOCKET.snd_proc], SOCKET_send_udp
mov [eax + SOCKET.rcv_proc], SOCKET_receive_dgram
384,10 → 373,6
 
align 4
.raw_ip:
push eax
init_queue (eax + SOCKET_QUEUE_LOCATION) ; Set up data receiving queue
pop eax
 
mov [eax + SOCKET.snd_proc], SOCKET_send_ip
mov [eax + SOCKET.rcv_proc], SOCKET_receive_dgram
mov [eax + SOCKET.connect_proc], IPv4_connect
396,10 → 381,6
 
align 4
.raw_icmp:
push eax
init_queue (eax + SOCKET_QUEUE_LOCATION) ; Set up data receiving queue
pop eax
 
mov [eax + SOCKET.snd_proc], SOCKET_send_icmp
mov [eax + SOCKET.rcv_proc], SOCKET_receive_dgram
mov [eax + SOCKET.connect_proc], IPv4_connect
416,19 → 397,16
ret
 
 
;-----------------------------------------------------------------;
; ;
; SOCKET_bind: Bind to a local port. ;
; ;
; IN: ecx = socket number ;
; edx = pointer to sockaddr struct ;
; esi = length of sockaddr struct ;
; ;
; OUT: eax = 0 on success ;
; eax = -1 on error ;
; ebx = errorcode on error ;
; ;
;-----------------------------------------------------------------;
;-----------------------------------------------------------------
;
; SOCKET_bind
;
; IN: socket number in ecx
; pointer to sockaddr struct in edx
; length of that struct in esi
; OUT: 0 on success
;
;-----------------------------------------------------------------
align 4
SOCKET_bind:
 
435,7 → 413,6
DEBUGF DEBUG_NETWORK_VERBOSE, "SOCKET_bind: socknum=%u sockaddr=%x length=%u\n", ecx, edx, esi
 
call SOCKET_num_to_ptr
test eax, eax
jz .invalid
 
cmp esi, 2
509,19 → 486,16
 
 
 
;-----------------------------------------------------------------;
; ;
; SOCKET_connect: Connect to the remote host. ;
; ;
; IN: ecx = socket number ;
; edx = pointer to sockaddr struct ;
; esi = length of sockaddr struct ;
; ;
; OUT: eax = 0 on success ;
; eax = -1 on error ;
; ebx = errorcode on error ;
; ;
;-----------------------------------------------------------------;
;-----------------------------------------------------------------
;
; SOCKET_connect
;
; IN: socket number in ecx
; pointer to sockaddr struct in edx
; length of that struct in esi
; OUT: 0 on success
;
;-----------------------------------------------------------------
align 4
SOCKET_connect:
 
528,7 → 502,6
DEBUGF DEBUG_NETWORK_VERBOSE, "SOCKET_connect: socknum=%u sockaddr=%x length=%u\n", ecx, edx, esi
 
call SOCKET_num_to_ptr
test eax, eax
jz .invalid
 
cmp esi, 8
570,18 → 543,15
ret
 
 
;-----------------------------------------------------------------;
; ;
; SOCKET_listen: Listen for incoming connections. ;
; ;
; IN: ecx = socket number ;
; edx = backlog in edx ;
; ;
; OUT: eax = 0 on success ;
; eax = -1 on error ;
; ebx = errorcode on error ;
; ;
;-----------------------------------------------------------------;
;-----------------------------------------------------------------
;
; SOCKET_listen
;
; IN: socket number in ecx
; backlog in edx
; OUT: eax is socket num, -1 on error
;
;-----------------------------------------------------------------
align 4
SOCKET_listen:
 
588,7 → 558,6
DEBUGF DEBUG_NETWORK_VERBOSE, "SOCKET_listen: socknum=%u backlog=%u\n", ecx, edx
 
call SOCKET_num_to_ptr
test eax, eax
jz .invalid
 
cmp [eax + SOCKET.Domain], AF_INET4
639,19 → 608,16
ret
 
 
;-----------------------------------------------------------------;
; ;
; SOCKET_accept: Accept an incoming connection. ;
; ;
; IN: ecx = socket number (of listening socket) ;
; edx = ptr to sockaddr struct ;
; esi = length of sockaddr struct ;
; ;
; OUT: eax = newly created socket num ;
; eax = -1 on error ;
; ebx = errorcode on error ;
; ;
;-----------------------------------------------------------------;
;-----------------------------------------------------------------
;
; SOCKET_accept
;
; IN: socket number in ecx
; addr in edx
; addrlen in esi
; OUT: eax is socket num, -1 on error
;
;-----------------------------------------------------------------
align 4
SOCKET_accept:
 
658,7 → 624,6
DEBUGF DEBUG_NETWORK_VERBOSE, "SOCKET_accept: socknum=%u sockaddr=%x length=%u\n", ecx, edx, esi
 
call SOCKET_num_to_ptr
test eax, eax
jz .invalid
 
test [eax + SOCKET.options], SO_ACCEPTCON
676,17 → 641,16
; Ok, we got a socket ptr
mov eax, [esi]
 
; Verify that it is (still) a valid socket
call SOCKET_check
jz .invalid
 
; Change sockets thread owner ID to that of the current thread
; Change thread ID to that of the current thread
mov ebx, [TASK_BASE]
mov ebx, [ebx + TASKDATA.pid]
mov [eax + SOCKET.TID], ebx
 
; Return socket number to caller
mov eax, [eax + SOCKET.Number]
; Convert it to a socket number
call SOCKET_ptr_to_num
jz .invalid ; FIXME ?
 
; and return it to caller
mov [esp+32], eax
ret
 
712,17 → 676,14
mov dword[esp+32], -1
ret
 
;-----------------------------------------------------------------;
; ;
; SOCKET_close: Close the socket (and connection). ;
; ;
; IN: ecx = socket number ;
; ;
; OUT: eax = 0 on success ;
; eax = -1 on error ;
; ebx = errorcode on error ;
; ;
;-----------------------------------------------------------------;
;-----------------------------------------------------------------
;
; SOCKET_close
;
; IN: socket number in ecx
; OUT: eax is socket num, -1 on error
;
;-----------------------------------------------------------------
align 4
SOCKET_close:
 
729,7 → 690,6
DEBUGF DEBUG_NETWORK_VERBOSE, "SOCKET_close: socknum=%u\n", ecx
 
call SOCKET_num_to_ptr
test eax, eax
jz .invalid
 
mov dword[esp+32], 0 ; The socket exists, so we will succeed in closing it.
752,6 → 712,7
ret
 
.tcp:
 
call TCP_usrclosed
 
test eax, eax
758,6 → 719,7
jz @f
call TCP_output ; If connection is not closed yet, send the FIN
@@:
 
ret
 
 
767,21 → 729,17
ret
 
 
;-----------------------------------------------------------------;
; ;
; SOCKET_receive: Receive some data from the remote end. ;
; ;
; IN: ecx = socket number ;
; edx = addr to application buffer ;
; edx = length of application buffer ;
; edi = flags ;
; ;
; OUT: eax = number of bytes copied ;
; eax = -1 on error ;
; eax = 0 when socket has been closed by the remote end ;
; ebx = errorcode on error ;
; ;
;-----------------------------------------------------------------;
;-----------------------------------------------------------------
;
; SOCKET_receive
;
; IN: socket number in ecx
; addr to buffer in edx
; length of buffer in esi
; flags in edi
; OUT: eax is number of bytes copied, -1 on error
;
;-----------------------------------------------------------------
align 4
SOCKET_receive:
 
788,7 → 746,6
DEBUGF DEBUG_NETWORK_VERBOSE, "SOCKET_receive: socknum=%u bufaddr=%x buflength=%u flags=%x\n", ecx, edx, esi, edi
 
call SOCKET_num_to_ptr
test eax, eax
jz .invalid
 
.loop:
805,8 → 762,8
test edi, MSG_DONTWAIT
jnz .return_err
 
test [eax + SOCKET.options], SO_NONBLOCK
jnz .return_err
; test [eax + SOCKET.options], SO_NONBLOCK
; jnz .return_err
 
call SOCKET_block
jmp .loop
825,7 → 782,7
.last_data:
test ecx, ecx
jz .return
call SOCKET_notify ; Call me again!
call SOCKET_notify
jmp .return
 
 
836,9 → 793,6
 
DEBUGF DEBUG_NETWORK_VERBOSE, "SOCKET_receive: DGRAM\n"
 
test edi, MSG_PEEK
jnz .peek
 
mov ebx, esi ; buffer length
 
get_from_queue (eax + SOCKET_QUEUE_LOCATION), SOCKET_QUEUE_SIZE, sizeof.socket_queue_entry, .wouldblock ; sets esi only on success.
870,11 → 824,7
 
call NET_BUFF_free
pop ecx eax ; return number of bytes copied to application
cmp [eax + SOCKET_QUEUE_LOCATION + queue.size], 0
je @f
call SOCKET_notify ; Queue another network event
@@:
xor ebx, ebx ; errorcode = 0 (no error)
xor ebx, ebx
ret
 
.too_small:
888,15 → 838,6
pop ebx
ret
 
.peek:
xor ebx, ebx
xor ecx, ecx
cmp [eax + SOCKET_QUEUE_LOCATION + queue.size], 0
je @f
mov esi, [eax + SOCKET_QUEUE_LOCATION + queue.r_ptr]
mov ecx, [esi + socket_queue_entry.data_size]
@@:
ret
 
 
align 4
960,20 → 901,18
ret
 
 
;-----------------------------------------------------------------;
; ;
; SOCKET_send: Send some data to the remote end. ;
; ;
; IN: ecx = socket number ;
; edx = pointer to data ;
; esi = data length ;
; edi = flags ;
; ;
; OUT: eax = number of bytes sent ;
; eax = -1 on error ;
; ebx = errorcode on error ;
; ;
;-----------------------------------------------------------------;
;-----------------------------------------------------------------
;
; SOCKET_send
;
;
; IN: socket number in ecx
; pointer to data in edx
; datalength in esi
; flags in edi
; OUT: -1 on error
;
;-----------------------------------------------------------------
align 4
SOCKET_send:
 
980,7 → 919,6
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
test eax, eax
jz .invalid
 
mov ecx, esi
1037,14 → 975,14
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 .error
ret
 
.error:
mov dword[esp+32], eax
mov dword[esp+20], ebx
mov dword[esp+32], -1
mov dword[esp+20], EMSGSIZE
ret
 
 
1054,14 → 992,14
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 .error
ret
 
.error:
mov dword[esp+32], eax
mov dword[esp+20], ebx
mov dword[esp+32], -1
mov dword[esp+20], EMSGSIZE
ret
 
 
1130,30 → 1068,26
ret
 
 
;-----------------------------------------------------------------;
; ;
; SOCKET_get_options: Read a socket option ;
; ;
; IN: ecx = socket number ;
; edx = pointer to socket options struct ;
; ;
; OUT: eax = 0 on success ;
; eax = -1 on error ;
; ebx = errorcode on error ;
; ;
;-----------------------------------------------------------------;
align 4
SOCKET_get_opt:
 
; FIXME:
;-----------------------------------------------------------------
;
; SOCKET_get_options
;
; IN: ecx = socket number
; edx = pointer to the options:
; dd level, optname, optval, optlen
; OUT: -1 on error
;
; At moment, uses only pseudo-optname -2 for get last_ack_number for TCP.
; TODO: find best way to notify that send()'ed data were acknowledged
; Also pseudo-optname -3 is valid and returns socket state, one of TCPS_*.
;
;-----------------------------------------------------------------
align 4
SOCKET_get_opt:
 
DEBUGF DEBUG_NETWORK_VERBOSE, "SOCKET_get_opt\n"
 
call SOCKET_num_to_ptr
test eax, eax
jz .invalid
 
cmp dword [edx], IP_PROTO_TCP
1192,18 → 1126,17
ret
 
 
;-----------------------------------------------------------------;
; ;
; SOCKET_set_options: Set a socket option. ;
; ;
; IN: ecx = socket number ;
; edx = pointer to socket options struct ;
; ;
; OUT: eax = 0 on success ;
; eax = -1 on error ;
; ebx = errorcode on error ;
; ;
;-----------------------------------------------------------------;
 
;-----------------------------------------------------------------
;
; SOCKET_set_options
;
; IN: ecx = socket number
; edx = pointer to the options:
; dd level, optname, optlen, optval
; OUT: -1 on error
;
;-----------------------------------------------------------------
align 4
SOCKET_set_opt:
 
1210,23 → 1143,24
DEBUGF DEBUG_NETWORK_VERBOSE, "SOCKET_set_opt\n"
 
call SOCKET_num_to_ptr
test eax, eax
jz .invalid
 
cmp [edx + socket_options.level], IP_PROTO_IP
je .ip
cmp [edx + socket_options.level], SOL_SOCKET
cmp dword [edx], SOL_SOCKET
jne .invalid
 
.socket:
cmp [edx + socket_options.optname], SO_BINDTODEVICE
jne .invalid
cmp dword [edx+4], SO_BINDTODEVICE
je .bind
 
.invalid:
mov dword[esp+32], -1
mov dword[esp+20], EINVAL
ret
 
.bind:
cmp [edx + socket_options.optlen], 0
cmp dword[edx+8], 0
je .unbind
 
movzx edx, byte[edx + socket_options.optval]
movzx edx, byte[edx + 12]
cmp edx, NET_DEVICES_MAX
ja .invalid
 
1246,42 → 1180,25
mov dword[esp+32], 0 ; success!
ret
 
.ip:
cmp [edx + socket_options.optname], IP_TTL
jne .invalid
 
.ttl:
mov bl, byte[edx + socket_options.optval]
mov [eax + IP_SOCKET.ttl], bl
 
mov dword[esp+32], 0 ; success!
ret
 
.already:
mov dword[esp+20], EALREADY
mov dword[esp+32], -1
ret
 
.invalid:
mov dword[esp+20], EINVAL
mov dword[esp+32], -1
ret
 
 
 
 
;-----------------------------------------------------------------;
; ;
; SOCKET_pair: Allocate a pair of linked local sockets. ;
; ;
; IN: / ;
; ;
; OUT: eax = socket1 num on success ;
; eax = -1 on error ;
; ebx = socket2 num on success ;
; ebx = errorcode on error ;
; ;
;-----------------------------------------------------------------;
;-----------------------------------------------------------------
;
; SOCKET_pair
;
; Allocates a pair of linked LOCAL domain sockets
;
; IN: /
; OUT: eax is socket1 num, -1 on error
; ebx is socket2 num
;
;-----------------------------------------------------------------
align 4
SOCKET_pair:
 
1319,7 → 1236,7
lea eax, [eax + STREAM_SOCKET.rcv]
call SOCKET_ring_create
test eax, eax
jz .nomem2
jz .nomem1
 
lea eax, [ebx + STREAM_SOCKET.rcv]
call SOCKET_ring_create
1329,31 → 1246,26
ret
 
.nomem2:
mov eax, [esp+20]
mov eax, ebx
call SOCKET_free
 
.nomem1:
mov eax, [esp+32]
call SOCKET_free
 
mov dword[esp+32], -1
mov dword[esp+20], ENOMEM
mov dword[esp+28], ENOMEM
ret
 
 
 
;-----------------------------------------------------------------;
; ;
; SOCKET_debug: Copy socket variables to application buffer. ;
; ;
; IN: ecx = socket number ;
; edx = pointer to application buffer ;
; ;
; OUT: eax = 0 on success ;
; eax = -1 on error ;
; ebx = errorcode on error ;
; ;
;-----------------------------------------------------------------;
;-----------------------------------------------------------------
;
; SOCKET_debug
;
; Copies socket variables to application buffer
;
; IN: ecx = socket number
; edx = pointer to buffer
;
; OUT: -1 on error
;-----------------------------------------------------------------
align 4
SOCKET_debug:
 
1365,7 → 1277,6
jz .returnall
 
call SOCKET_num_to_ptr
test eax, eax
jz .invalid
 
mov esi, eax
1392,31 → 1303,22
 
.invalid:
mov dword[esp+32], -1
mov dword[esp+20], EINVAL
mov dword[esp+28], EINVAL
ret
 
 
;-----------------------------------------------------------------;
; ____ ____ ;
; \ / End of sockets API \ / ;
; \/ \/ ;
; () Internally used functions follow () ;
; ;
;-----------------------------------------------------------------;
 
 
;-----------------------------------------------------------------;
; ;
; SOCKET_find_port: ;
; Fill in the local port number for TCP and UDP sockets ;
; This procedure always works because the number of sockets is ;
; limited to a smaller number then the number of possible ports ;
; ;
; IN: eax = socket pointer ;
; ;
; OUT: / ;
; ;
;-----------------------------------------------------------------;
;-----------------------------------------------------------------
;
; SOCKET_find_port
;
; Fills in the local port number for TCP and UDP sockets
; This procedure always works because the number of sockets is
; limited to a smaller number then the number of possible ports
;
; IN: eax = socket pointer
; OUT: /
;
;-----------------------------------------------------------------
align 4
SOCKET_find_port:
 
1465,20 → 1367,19
 
 
 
;-----------------------------------------------------------------;
; ;
; SOCKET_check_port (to be used with AF_INET only!) ;
; ;
; Checks if a local port number is unused ;
; If the proposed port number is unused, it is filled in in the ;
; socket structure ;
; ;
; IN: eax = socket ptr ;
; bx = proposed socket number (network byte order) ;
; ;
; OUT: ZF = set on error ;
; ;
;-----------------------------------------------------------------;
;-----------------------------------------------------------------
;
; SOCKET_check_port (to be used with AF_INET only!)
;
; Checks if a local port number is unused
; If the proposed port number is unused, it is filled in in the socket structure
;
; IN: eax = socket ptr (to find out if its a TCP/UDP socket)
; bx = proposed socket number (network byte order)
;
; OUT: ZF = set on error
;
;-----------------------------------------------------------------
align 4
SOCKET_check_port:
 
1528,20 → 1429,22
 
 
 
;-----------------------------------------------------------------;
; ;
; SOCKET_input: Update a (stateless) socket with received data. ;
; ;
; Note: The socket's mutex should already be set ! ;
; ;
; IN: eax = socket ptr ;
; ecx = data size ;
; esi = ptr to data ;
; [esp] = ptr to buf ;
; ;
; OUT: / ;
; ;
;-----------------------------------------------------------------;
;-----------------------------------------------------------------
;
; SOCKET_input
;
; Updates a (stateless) socket with received data
;
; Note: the mutex should already be set !
;
; IN: eax = socket ptr
; ecx = data size
; esi = ptr to data
; [esp] = ptr to buf
;
; OUT: /
;
;-----------------------------------------------------------------
align 4
SOCKET_input:
 
1571,21 → 1474,14
call mutex_unlock
popa
 
add esp, 8
call NET_BUFF_free
ret
 
 
;-----------------------------------------------------------------;
; ;
; SOCKET_ring_create: Create a ringbuffer for sockets. ;
; ;
; IN: eax = ptr to ring struct ;
; ;
; OUT: eax = 0 on error ;
; eax = start ptr ;
; ;
;-----------------------------------------------------------------;
;--------------------------
;
; eax = ptr to ring struct (just a buffer of the right size)
;
align 4
SOCKET_ring_create:
 
1598,7 → 1494,7
test eax, eax
jz .fail
 
DEBUGF DEBUG_NETWORK_VERBOSE, "SOCKET_ring_create: %x\n", eax
DEBUGF DEBUG_NETWORK_VERBOSE, "SOCKET_ring_created: %x\n", eax
 
pusha
lea ecx, [esi + RING_BUFFER.mutex]
1613,25 → 1509,23
mov [esi + RING_BUFFER.end_ptr], eax
mov eax, esi
 
pop esi
ret
 
.fail:
DEBUGF DEBUG_NETWORK_ERROR, "SOCKET_ring_create: Out of memory!\n"
pop esi
ret
 
;-----------------------------------------------------------------;
; ;
; SOCKET_ring_write: Write data to ring buffer. ;
; ;
; IN: eax = ptr to ring struct ;
; ecx = data size ;
; esi = ptr to data ;
; ;
; OUT: ecx = number of bytes stored ;
; ;
;-----------------------------------------------------------------;
;-----------------------------------------------------------------
;
; SOCKET_ring_write
;
; Adds data to a stream socket, and updates write pointer and size
;
; IN: eax = ptr to ring struct
; ecx = data size
; esi = ptr to data
;
; OUT: ecx = number of bytes stored
;
;-----------------------------------------------------------------
align 4
SOCKET_ring_write:
 
1691,22 → 1585,22
 
ret
 
;-----------------------------------------------------------------;
; ;
; SOCKET_ring_read: Read from ring buffer ;
; ;
; IN: eax = ring struct ptr ;
; ecx = bytes to read ;
; edx = offset ;
; edi = ptr to buffer start ;
; ;
; OUT: eax = unchanged ;
; ecx = number of bytes read (0 on error) ;
; edx = destroyed ;
; esi = destroyed ;
; edi = ptr to buffer end ;
; ;
;-----------------------------------------------------------------;
;-----------------------------------------------------------------
;
; SOCKET_ring_read
;
; IN: eax = ring struct ptr
; ecx = bytes to read
; edx = offset
; edi = ptr to buffer start
;
; OUT: eax = unchanged
; ecx = number of bytes read (0 on error)
; edx = destroyed
; esi = destroyed
; edi = ptr to buffer end
;
;-----------------------------------------------------------------
align 4
SOCKET_ring_read:
 
1765,16 → 1659,18
jmp .copy
 
 
;-----------------------------------------------------------------;
; ;
; SOCKET_ring_free: Free data from a ringbuffer ;
; ;
; IN: eax = ptr to ring struct ;
; ecx = data size ;
; ;
; OUT: ecx = number of freed bytes ;
; ;
;-----------------------------------------------------------------;
;-----------------------------------------------------------------
;
; SOCKET_ring_free
;
; Free's some bytes from the ringbuffer
;
; IN: eax = ptr to ring struct
; ecx = data size
;
; OUT: ecx = number of bytes free-ed
;
;-----------------------------------------------------------------
align 4
SOCKET_ring_free:
 
1815,15 → 1711,16
ret
 
 
;-----------------------------------------------------------------;
; ;
; SOCKET_block: Suspend the thread attached to a socket. ;
; ;
; IN: eax = socket ptr ;
; ;
; OUT: eax = unchanged ;
; ;
;-----------------------------------------------------------------;
;-----------------------------------------------------------------
;
; SOCKET_block
;
; Suspends the thread attached to a socket
;
; IN: eax = socket ptr
; OUT: eax = unchanged
;
;-----------------------------------------------------------------
align 4
SOCKET_block:
 
1857,15 → 1754,16
ret
 
 
;-----------------------------------------------------------------;
; ;
; SOCKET_notify: Wake up socket owner thread. ;
; ;
; IN: eax = socket ptr ;
; ;
; OUT: eax = unchanged ;
; ;
;-----------------------------------------------------------------;
;-----------------------------------------------------------------
;
; SOCKET_notify
;
; notify's the owner of a socket that something happened
;
; IN: eax = socket ptr
; OUT: eax = unchanged
;
;-----------------------------------------------------------------
align 4
SOCKET_notify:
 
1904,7 → 1802,7
test [eax + SOCKET.state], SS_BLOCKED
jnz .un_block
 
; Socket and thread exists and socket is of non blocking type.
; socket and thread exists and socket is of non blocking type.
; We'll try to flag an event to the thread.
shl ecx, 8
or [ecx + SLOT_BASE + APPDATA.event_mask], EVENT_NETWORK
1915,7 → 1813,7
 
 
.un_block:
; Socket and thread exists and socket is of blocking type
; socket and thread exists and socket is of blocking type
; We'll try to unblock it.
and [eax + SOCKET.state], not SS_BLOCKED ; Clear the 'socket is blocked' flag
mov [esi + TASKDATA.state], 0 ; Run the thread
1925,20 → 1823,19
ret
 
 
;-----------------------------------------------------------------;
; ;
; SOCKET_alloc: ;
; Allocate memory for socket and put new socket into the list. ;
; Newly created socket is initialized with calling PID and socket ;
; number. ;
; ;
; IN: / ;
; ;
; OUT: eax = socket ptr on success ;
; eax = 0 on error ;
; edi = socket number on success ;
; ;
;-----------------------------------------------------------------;
;--------------------------------------------------------------------
;
; SOCKET_alloc
;
; Allocate memory for socket data and put new socket into the list
; Newly created socket is initialized with calling PID and number and
; put into beginning of list (which is a fastest way).
;
; IN: /
; OUT: eax = 0 on error, socket ptr otherwise
; edi = socket number
;
;--------------------------------------------------------------------
align 4
SOCKET_alloc:
 
1945,9 → 1842,9
push ebx
 
stdcall kernel_alloc, SOCKETBUFFSIZE
DEBUGF DEBUG_NETWORK_VERBOSE, "SOCKET_alloc: ptr=%x\n", eax
or eax, eax
jz .nomem
DEBUGF DEBUG_NETWORK_VERBOSE, "SOCKET_alloc: ptr=%x\n", eax
jz .exit
 
; zero-initialize allocated memory
push eax
2028,15 → 1925,12
mov ecx, socket_mutex
call mutex_unlock
popa
 
.exit:
pop ebx
 
ret
 
.nomem:
DEBUGF DEBUG_NETWORK_ERROR, "SOCKET_alloc: Out of memory!\n"
pop ebx
ret
 
.not_yet:
mov dword[esp+20], ENOTCONN
mov dword[esp+32], -1
2043,17 → 1937,17
ret
 
 
;-----------------------------------------------------------------;
; ;
; SOCKET_free: ;
; Free socket data memory and remove socket from the list. ;
; Caller should lock and unlock socket_mutex. ;
; ;
; IN: eax = socket ptr ;
; ;
; OUT: / ;
; ;
;-----------------------------------------------------------------;
;----------------------------------------------------
;
; SOCKET_free
;
; Free socket data memory and remove socket from the list
; Caller should lock and unlock socket_mutex
;
; IN: eax = socket ptr
; OUT: /
;
;----------------------------------------------------
align 4
SOCKET_free:
 
2069,20 → 1963,17
call mutex_lock
popa
 
cmp [eax + SOCKET.Type], SOCK_STREAM
jne .no_stream
cmp [eax + SOCKET.Domain], AF_INET4
jnz .no_tcp
 
cmp [eax + SOCKET.Protocol], IP_PROTO_TCP
jnz .no_tcp
 
mov ebx, eax
cmp [eax + STREAM_SOCKET.rcv.start_ptr], 0
je @f
stdcall free_kernel_space, [eax + STREAM_SOCKET.rcv.start_ptr]
@@:
cmp [ebx + STREAM_SOCKET.snd.start_ptr], 0
je @f
stdcall free_kernel_space, [ebx + STREAM_SOCKET.snd.start_ptr]
@@:
stdcall kernel_free, [ebx + STREAM_SOCKET.rcv.start_ptr]
stdcall kernel_free, [ebx + STREAM_SOCKET.snd.start_ptr]
mov eax, ebx
.no_stream:
.no_tcp:
 
DEBUGF DEBUG_NETWORK_VERBOSE, "SOCKET_free: freeing socket %x\n", eax
push eax ; this will be passed to kernel_free
2109,22 → 2000,16
.error:
ret
 
.error1:
pop ebx
DEBUGF DEBUG_NETWORK_ERROR, "SOCKET_free: error!\n"
DEBUGF DEBUG_NETWORK_ERROR, "socket ptr=0x%x caller=0x%x\n", eax, [esp]
ret
 
;-----------------------------------------------------------------;
; ;
; SOCKET_fork: Create a child socket. ;
; ;
; IN: ebx = socket number ;
; ;
; OUT: eax = child socket number on success ;
; eax = 0 on error ;
; ;
;-----------------------------------------------------------------;
;------------------------------------
;
; SOCKET_fork
;
; Create a child socket
;
; IN: socket nr in ebx
; OUT: child socket nr in eax
;
;-----------------------------------
align 4
SOCKET_fork:
 
2173,16 → 2058,17
ret
 
 
;-----------------------------------------------------------------;
; ;
; SOCKET_num_to_ptr: Get socket structure address by its number. ;
; ;
; IN: ecx = socket number ;
; ;
; OUT: eax = socket ptr ;
; eax = 0 on error ;
; ;
;-----------------------------------------------------------------;
;---------------------------------------------------
;
; SOCKET_num_to_ptr
;
; Get socket structure address by its number
;
; IN: ecx = socket number
; OUT: eax = 0 on error, socket ptr otherwise
; ZF = set on error
;
;---------------------------------------------------
align 4
SOCKET_num_to_ptr:
 
2194,13 → 2080,16
popa
 
mov eax, net_sockets
 
.next_socket:
mov eax, [eax + SOCKET.NextPtr]
test eax, eax
or eax, eax
jz .error
cmp [eax + SOCKET.Number], ecx
jne .next_socket
 
test eax, eax
 
pusha
mov ecx, socket_mutex
call mutex_unlock
2220,17 → 2109,17
ret
 
 
;-----------------------------------------------------------------;
; ;
; SOCKET_ptr_to_num: Get socket number by its address. ;
; ;
; IN: eax = socket ptr ;
; ;
; OUT: eax = socket number ;
; eax = 0 on error ;
; ZF = set on error ;
; ;
;-----------------------------------------------------------------;
;---------------------------------------------------
;
; SOCKET_ptr_to_num
;
; Get socket number by its address
;
; IN: eax = socket ptr
; OUT: eax = 0 on error, socket num otherwise
; ZF = set on error
;
;---------------------------------------------------
align 4
SOCKET_ptr_to_num:
 
2249,23 → 2138,22
ret
 
 
;-----------------------------------------------------------------;
; ;
; SOCKET_check: Checks if the given ptr is really a socket ptr. ;
; ;
; IN: eax = socket ptr ;
; ;
; OUT: eax = 0 on error ;
; ZF = set on error ;
; ;
;-----------------------------------------------------------------;
;---------------------------------------------------
;
; SOCKET_check
;
; checks if the given value is really a socket ptr
;
; IN: eax = socket ptr
; OUT: eax = 0 on error, unchanged otherwise
; ZF = set on error
;
;---------------------------------------------------
align 4
SOCKET_check:
 
DEBUGF DEBUG_NETWORK_VERBOSE, "SOCKET_check: %x\n", eax
 
test eax, eax
jz .error
push ebx
mov ebx, net_sockets
 
2280,24 → 2168,21
mov eax, ebx
test eax, eax
pop ebx
ret
 
.error:
DEBUGF DEBUG_NETWORK_ERROR, "SOCKET_check: called with argument 0\n"
DEBUGF DEBUG_NETWORK_ERROR, "stack: 0x%x, 0x%x, 0x%x\n", [esp], [esp+4], [esp+8]
ret
 
 
 
;-----------------------------------------------------------------;
; ;
; SOCKET_check_owner: Check if the caller app owns the socket. ;
; ;
; IN: eax = socket ptr ;
; ;
; OUT: ZF = true/false ;
; ;
;-----------------------------------------------------------------;
;---------------------------------------------------
;
; SOCKET_check_owner
;
; checks if the caller application owns the socket
;
; IN: eax = socket ptr
; OUT: ZF = true/false
;
;---------------------------------------------------
align 4
SOCKET_check_owner:
 
2314,18 → 2199,18
 
 
 
;-----------------------------------------------------------------;
; ;
; SOCKET_process_end: ;
; Kernel calls this function when a certain process ends. ;
; This function will check if the process had any open sockets, ;
; and update them accordingly (clean up). ;
; ;
; IN: edx = pid ;
; ;
; OUT: / ;
; ;
;-----------------------------------------------------------------;
;------------------------------------------------------
;
; SOCKET_process_end
;
; Kernel calls this function when a certain process ends
; This function will check if the process had any open sockets
; And update them accordingly (clean up)
;
; IN: edx = pid
; OUT: /
;
;------------------------------------------------------
align 4
SOCKET_process_end:
 
2392,15 → 2277,15
 
 
 
;-----------------------------------------------------------------;
; ;
; SOCKET_is_connecting: Update socket state. ;
; ;
; IN: eax = socket ptr ;
; ;
; OUT: / ;
; ;
;-----------------------------------------------------------------;
;-----------------------------------------------------------------
;
; SOCKET_is_connecting
;
; IN: eax = socket ptr
; OUT: /
;
;-----------------------------------------------------------------
 
align 4
SOCKET_is_connecting:
 
2408,19 → 2293,20
 
and [eax + SOCKET.state], not (SS_ISCONNECTED + SS_ISDISCONNECTING + SS_ISCONFIRMING)
or [eax + SOCKET.state], SS_ISCONNECTING
 
ret
 
 
 
;-----------------------------------------------------------------;
; ;
; SOCKET_is_connected: Update socket state. ;
; ;
; IN: eax = socket ptr ;
; ;
; OUT: / ;
; ;
;-----------------------------------------------------------------;
;-----------------------------------------------------------------
;
; SOCKET_is_connected
;
; IN: eax = socket ptr
; OUT: /
;
;-----------------------------------------------------------------
 
align 4
SOCKET_is_connected:
 
2428,20 → 2314,21
 
and [eax + SOCKET.state], not (SS_ISCONNECTING + SS_ISDISCONNECTING + SS_ISCONFIRMING)
or [eax + SOCKET.state], SS_ISCONNECTED
 
jmp SOCKET_notify
 
 
 
 
;-----------------------------------------------------------------;
; ;
; SOCKET_is_disconnecting: Update socket state. ;
; ;
; IN: eax = socket ptr ;
; ;
; OUT: / ;
; ;
;-----------------------------------------------------------------;
;-----------------------------------------------------------------
;
; SOCKET_is_disconnecting
;
; IN: eax = socket ptr
; OUT: /
;
;-----------------------------------------------------------------
 
align 4
SOCKET_is_disconnecting:
 
2449,19 → 2336,20
 
and [eax + SOCKET.state], not (SS_ISCONNECTING)
or [eax + SOCKET.state], SS_ISDISCONNECTING + SS_CANTRCVMORE + SS_CANTSENDMORE
 
jmp SOCKET_notify
 
 
 
;-----------------------------------------------------------------;
; ;
; SOCKET_is_disconnected: Update socket state. ;
; ;
; IN: eax = socket ptr ;
; ;
; OUT: / ;
; ;
;-----------------------------------------------------------------;
;-----------------------------------------------------------------
;
; SOCKET_is_disconnected
;
; IN: eax = socket ptr
; OUT: /
;
;-----------------------------------------------------------------
 
align 4
SOCKET_is_disconnected:
 
2469,19 → 2357,21
 
and [eax + SOCKET.state], not (SS_ISCONNECTING + SS_ISCONNECTED + SS_ISDISCONNECTING)
or [eax + SOCKET.state], SS_CANTRCVMORE + SS_CANTSENDMORE
 
 
jmp SOCKET_notify
 
 
 
;-----------------------------------------------------------------;
; ;
; SOCKET_cant_recv_more: Update socket state. ;
; ;
; IN: eax = socket ptr ;
; ;
; OUT: / ;
; ;
;-----------------------------------------------------------------;
;-----------------------------------------------------------------
;
; SOCKET_cant_recv_more
;
; IN: eax = socket ptr
; OUT: /
;
;-----------------------------------------------------------------
 
align 4
SOCKET_cant_recv_more:
 
2488,19 → 2378,22
DEBUGF DEBUG_NETWORK_VERBOSE, "SOCKET_cant_recv_more: %x\n", eax
 
or [eax + SOCKET.state], SS_CANTRCVMORE
jmp SOCKET_notify
 
call SOCKET_notify
 
ret
 
;-----------------------------------------------------------------;
; ;
; SOCKET_cant_send_more: Update socket state. ;
; ;
; IN: eax = socket ptr ;
; ;
; OUT: / ;
; ;
;-----------------------------------------------------------------;
 
 
;-----------------------------------------------------------------
;
; SOCKET_cant_send_more
;
; IN: eax = socket ptr
; OUT: /
;
;-----------------------------------------------------------------
 
align 4
SOCKET_cant_send_more:
 
2508,8 → 2401,11
 
or [eax + SOCKET.state], SS_CANTSENDMORE
mov [eax + SOCKET.snd_proc], .notconn
jmp SOCKET_notify
 
call SOCKET_notify
 
ret
 
.notconn:
mov dword[esp+20], ENOTCONN
mov dword[esp+32], -1
/kernel/branches/Kolibri-acpi/network/udp.inc
36,11 → 36,13
endg
 
 
;-----------------------------------------------------------------;
; ;
; UDP_init: This function resets all UDP variables ;
; ;
;-----------------------------------------------------------------;
;-----------------------------------------------------------------
;
; UDP_init
;
; This function resets all UDP variables
;
;-----------------------------------------------------------------
macro UDP_init {
 
xor eax, eax
55,15 → 57,15
; Pseudoheader
mov edx, IP_PROTO_UDP
 
add dl, byte[IP1+1]
adc dh, byte[IP1+0]
adc dl, byte[IP1+3]
adc dh, byte[IP1+2]
add dl, [IP1+1]
adc dh, [IP1+0]
adc dl, [IP1+3]
adc dh, [IP1+2]
 
adc dl, byte[IP2+1]
adc dh, byte[IP2+0]
adc dl, byte[IP2+3]
adc dh, byte[IP2+2]
adc dl, [IP2+1]
adc dh, [IP2+0]
adc dl, [IP2+3]
adc dh, [IP2+2]
 
adc dl, cl ; byte[esi+UDP_header.Length+1]
adc dh, ch ; byte[esi+UDP_header.Length+0]
96,20 → 98,23
}
 
 
;-----------------------------------------------------------------;
; ;
; UDP_input: Inject the UDP data in the application sockets. ;
; ;
; IN: [esp] = ptr to buffer ;
; ebx = ptr to device struct ;
; ecx = UDP packet size ;
; edx = ptr to IPv4 header ;
; esi = ptr to UDP packet data ;
; edi = interface number*4 ;
; ;
; OUT: / ;
; ;
;-----------------------------------------------------------------;
;-----------------------------------------------------------------
;
; UDP_input:
;
; Called by IPv4_input,
; this procedure will inject the udp data diagrams in the application sockets.
;
; IN: [esp] = Pointer to buffer
; [esp+4] = size of buffer
; ebx = ptr to device struct
; ecx = UDP Packet size
; esi = ptr to UDP header
; edi = ptr to ipv4 source and dest address
;
; OUT: /
;
;-----------------------------------------------------------------
align 4
UDP_input:
 
122,8 → 127,7
 
; otherwise, we will re-calculate the checksum and add it to this value, thus creating 0 when it is correct
 
mov eax, edx
UDP_checksum (eax+IPv4_header.SourceAddress), (eax+IPv4_header.DestinationAddress)
UDP_checksum (edi), (edi+4)
jnz .checksum_mismatch
 
.no_checksum:
144,7 → 148,9
 
mov cx, [esi + UDP_header.SourcePort]
mov dx, [esi + UDP_header.DestinationPort]
mov edi, [edi + 4] ; ipv4 source address
mov eax, net_sockets
 
.next_socket:
mov eax, [eax + SOCKET.NextPtr]
or eax, eax
166,15 → 172,15
call mutex_unlock
popa
 
;;; TODO: when packet is processed, check more sockets?!
;;; TODO: when packet is processed, check more sockets!
 
; FIXME: check remote IP if possible
;
; cmp [eax + IP_SOCKET.RemoteIP], 0xffffffff
; je @f
; cmp [eax + IP_SOCKET.RemoteIP],
; cmp [eax + IP_SOCKET.RemoteIP], edi
; jne .next_socket
; @@:
;
; FIXME: UDP should check remote IP, but not under all circumstances!
 
cmp [eax + UDP_SOCKET.RemotePort], 0
je .updateport
188,6 → 194,7
popa
 
.updatesock:
call NET_ptr_to_num4
inc [UDP_PACKETS_RX + edi]
 
movzx ecx, [esi + UDP_header.Length]
225,17 → 232,17
 
 
 
;-----------------------------------------------------------------;
; ;
; UDP_output: Create an UDP packet. ;
; ;
; IN: eax = socket pointer ;
; ecx = number of bytes to send ;
; esi = pointer to data ;
; ;
; OUT: eax = -1 on error ;
; ;
;-----------------------------------------------------------------;
;-----------------------------------------------------------------
;
; UDP_output
;
; IN: eax = socket pointer
; ecx = number of bytes to send
; esi = pointer to data
;
; OUT: eax = -1 on error
;
;-----------------------------------------------------------------
 
align 4
UDP_output:
250,11 → 257,10
 
sub esp, 4 ; Data ptr will be placed here
push edx esi
mov edx, [eax + IP_SOCKET.LocalIP]
mov ebx, [eax + IP_SOCKET.device]
mov edx, [eax + IP_SOCKET.LocalIP]
mov edi, [eax + IP_SOCKET.RemoteIP]
mov al, [eax + IP_SOCKET.ttl]
mov ah, IP_PROTO_UDP
mov eax, [eax + IP_SOCKET.RemoteIP]
mov di, IP_PROTO_UDP shl 8 + 128
add ecx, sizeof.UDP_header
call IPv4_output
jz .fail
300,17 → 306,15
 
 
 
;-----------------------------------------------------------------;
; ;
; UDP_connect ;
; ;
; IN: eax = socket pointer ;
; ;
; OUT: eax = 0 on success ;
; eax = -1 on error ;
; ebx = error code on error ;
; ;
;-----------------------------------------------------------------;
;-----------------------------------------------------------------
;
; UDP_connect
;
; IN: eax = socket pointer
; OUT: eax = 0 ok / -1 error
; ebx = error code
;
;-------------------------
align 4
UDP_connect:
 
344,6 → 348,10
@@:
 
push eax
init_queue (eax + SOCKET_QUEUE_LOCATION) ; Set up data receiving queue
pop eax
 
push eax
lea ecx, [eax + SOCKET.mutex]
call mutex_unlock
pop eax
354,15 → 362,14
ret
 
 
;-----------------------------------------------------------------;
; ;
; UDP_disconnect ;
; ;
; IN: eax = socket pointer ;
; ;
; OUT: eax = socket pointer ;
; ;
;-----------------------------------------------------------------;
;-----------------------------------------------------------------
;
; UDP_disconnect
;
; IN: eax = socket pointer
; OUT: eax = socket pointer
;
;-------------------------
align 4
UDP_disconnect:
 
376,17 → 383,20
 
 
 
;-----------------------------------------------------------------;
; ;
; UDP_api: This function is called by system function 76 ;
; ;
; IN: bl = subfunction number in bl ;
; bh = device number in bh ;
; ecx, edx, .. depends on subfunction ;
; ;
; OUT: depends on subfunction ;
; ;
;-----------------------------------------------------------------;
;---------------------------------------------------------------------------
;
; UDP_API
;
; This function is called by system function 75
;
; IN: subfunction number in bl
; device number in bh
; ecx, edx, .. depends on subfunction
;
; OUT:
;
;---------------------------------------------------------------------------
 
align 4
UDP_api:
 
/kernel/branches/Kolibri-acpi/network/loopback.inc
14,7 → 14,7
;; ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 
$Revision: 5976 $
$Revision: 5523 $
 
iglobal
align 4
61,15 → 61,15
.fail:
}
 
;-----------------------------------------------------------------;
; ;
; LOOP_input ;
; ;
; IN: [esp+4] = Pointer to buffer ;
; ;
; OUT: / ;
; ;
;-----------------------------------------------------------------;
;-----------------------------------------------------------------
;
; LOOP_input
;
; IN: [esp+4] = Pointer to buffer
;
; OUT: /
;
;-----------------------------------------------------------------
align 4
LOOP_input:
 
105,19 → 105,19
ret
 
 
;-----------------------------------------------------------------;
; ;
; LOOP_output ;
; ;
; IN: ecx = packet size ;
; edi = address family ;
; ;
; OUT: eax = start of net frame / 0 on error ;
; ebx = to device structure ;
; ecx = unchanged (packet size of embedded data) ;
; edi = start of payload ;
; ;
;-----------------------------------------------------------------;
;-----------------------------------------------------------------
;
; LOOP_output
;
; IN: ecx = packet size
; edi = address family
;
; OUT: eax = start of net frame / 0 on error
; ebx = to device structure
; ecx = unchanged (packet size of embedded data)
; edi = start of payload
;
;-----------------------------------------------------------------
align 4
LOOP_output:
 
/kernel/branches/Kolibri-acpi/network/stack.inc
53,13 → 53,7
IP_PROTO_ICMP = 1
IP_PROTO_TCP = 6
IP_PROTO_UDP = 17
IP_PROTO_RAW = 255
 
; IP options
IP_TOS = 1
IP_TTL = 2
IP_HDRINCL = 3
 
; PPP protocol numbers
PPP_PROTO_IPv4 = 0x2100
PPP_PROTO_IPV6 = 0x5780
77,9 → 71,6
SOCK_DGRAM = 2
SOCK_RAW = 3
 
; Socket level
SOL_SOCKET = 0xffff
 
; Socket options
SO_ACCEPTCON = 1 shl 0
SO_BROADCAST = 1 shl 1
98,6 → 89,10
MSG_PEEK = 0x02
MSG_DONTWAIT = 0x40
 
; Socket level
SOL_SOCKET = 0
 
 
; Socket States
SS_NOFDREF = 0x0001 ; no file table ref any more
SS_ISCONNECTED = 0x0002 ; socket connected to a peer
/kernel/branches/Kolibri-acpi/network/tcp.inc
201,11 → 201,13
endg
 
 
;-----------------------------------------------------------------;
; ;
; TCP_init: Resets all TCP variables. ;
; ;
;-----------------------------------------------------------------;
;-----------------------------------------------------------------
;
; TCP_init
;
; This function resets all TCP variables
;
;-----------------------------------------------------------------
macro TCP_init {
 
xor eax, eax
244,17 → 246,19
include 'tcp_output.inc'
 
 
;------------------------------------------------------------------;
; ;
; TCP_api: This function is called by system function 76 ;
; ;
; IN: bl = subfunction number ;
; bh = device number ;
; ecx, edx, .. depends on subfunction ;
; ;
; OUT: depends on subfunction ;
; ;
;------------------------------------------------------------------;
;---------------------------------------------------------------------------
;
; TCP_API
;
; This function is called by system function 76
;
; IN: subfunction number in bl
; device number in bh
; ecx, edx, .. depends on subfunction
;
; OUT:
;
;---------------------------------------------------------------------------
align 4
TCP_api:
 
/kernel/branches/Kolibri-acpi/network/tcp_input.inc
14,35 → 14,36
;; ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 
$Revision: 5976 $
$Revision: 5522 $
 
;-----------------------------------------------------------------;
; ;
; TCP_input: Add a segment to the incoming TCP queue. ;
; ;
; IN: [esp] = ptr to buffer ;
; ebx = ptr to device struct ;
; ecx = TCP segment size ;
; edx = ptr to IPv4 header ;
; esi = ptr to TCP segment ;
; edi = interface number*4 ;
; ;
; OUT: / ;
; ;
;-----------------------------------------------------------------;
;-----------------------------------------------------------------
;
; TCP_input:
;
; Add a segment to the incoming TCP queue
;
; IN: [esp] = ptr to buffer
; ebx = ptr to device struct
; ecx = segment size
; esi = ptr to TCP segment
; edi = ptr to ipv4 source address, followed by ipv4 dest address
;
; OUT: /
;
;-----------------------------------------------------------------
 
align 4
TCP_input:
 
; record the current time
push [timer_ticks] ; in 1/100 seconds
push ebx ecx esi edx ; mind the order (see TCP_queue_entry struct)
push ebx ecx esi edi ; mind the order (see TCP_queue_entry struct)
mov esi, esp
 
push edi
add_to_queue TCP_queue, TCP_QUEUE_SIZE, sizeof.TCP_queue_entry, .fail
pop edi
add esp, sizeof.TCP_queue_entry
 
call NET_ptr_to_num4
inc [TCP_segments_rx + edi]
 
xor edx, edx
54,13 → 55,12
ret
 
.fail:
pop edi
DEBUGF DEBUG_NETWORK_VERBOSE, "TCP incoming queue is full, discarding packet!\n"
 
call NET_ptr_to_num4
inc [TCP_segments_missed + edi]
 
add esp, sizeof.TCP_queue_entry - 4
add esp, sizeof.TCP_queue_entry - 8
call NET_BUFF_free
ret
 
94,7 → 94,7
 
mov ebx, [esi + TCP_queue_entry.device_ptr]
mov ecx, [esi + TCP_queue_entry.segment_size]
mov edi, [esi + TCP_queue_entry.ip_ptr] ; ptr to ipv4 header
mov edi, [esi + TCP_queue_entry.ip_ptr] ; ptr to ipv4 source address, followed by ipv4 destination address
mov esi, [esi + TCP_queue_entry.segment_ptr] ; change esi last
 
DEBUGF DEBUG_NETWORK_VERBOSE, "TCP_input: size=%u time=%d\n", ecx, [timer_ticks]
111,7 → 111,7
push ecx esi
pushw [esi + TCP_header.Checksum]
mov [esi + TCP_header.Checksum], 0
TCP_checksum (edi+IPv4_header.SourceAddress), (edi+IPv4_header.DestinationAddress)
TCP_checksum (edi), (edi+4)
pop cx ; previous checksum
cmp cx, dx
pop edx ecx
170,7 → 170,7
jne .socket_loop
 
mov eax, [ebx + IP_SOCKET.RemoteIP]
cmp eax, [edi + IPv4_header.SourceAddress]
cmp eax, [edi] ; Ipv4 source address
je @f
test eax, eax
jnz .socket_loop
233,7 → 233,7
call mutex_unlock
popa
 
push ecx edx esi edi
push ecx edx esi edi ;;;
call SOCKET_fork
pop edi esi edx ecx
 
244,7 → 244,7
 
mov [temp_bits], TCP_BIT_DROPSOCKET
 
push [edi + IPv4_header.DestinationAddress]
push dword [edi + 4] ; Ipv4 destination addres
pop [ebx + IP_SOCKET.LocalIP]
 
push [edx + TCP_header.DestinationPort]
485,8 → 485,8
inc eax
call TCP_xmit_timer
jmp .rtt_done
 
.no_timestamp_rtt:
 
cmp [ebx + TCP_SOCKET.t_rtt], 0
je .rtt_done
mov eax, [edx + TCP_header.AckNumber]
494,6 → 494,7
jbe .rtt_done
mov eax, [ebx + TCP_SOCKET.t_rtt]
call TCP_xmit_timer
 
.rtt_done:
 
; update window pointers
1210,7 → 1211,7
 
;;; TODO: check if it's a broadcast or multicast, and drop if so
 
push [edi + IPv4_header.SourceAddress]
push dword [edi] ; Ipv4 source addres
pop [ebx + IP_SOCKET.RemoteIP]
 
push [edx + TCP_header.SourcePort]
1672,13 → 1673,11
 
.respond_seg_ack:
mov cl, TH_RST
xor ebx, ebx ; FIXME: find a way to get the receiving device ptr
call TCP_respond_segment
jmp .drop_no_socket
 
.respond_seg_syn:
mov cl, TH_RST + TH_ACK
xor ebx, ebx ; FIXME: find a way to get the receiving device ptr
call TCP_respond_segment
jmp .drop_no_socket
 
/kernel/branches/Kolibri-acpi/network/tcp_timer.inc
23,6 → 23,9
timer_flag_wait = 1 shl 4
 
 
;----------------------
; 160 ms timer
;----------------------
macro TCP_timer_160ms {
 
local .loop
147,9 → 150,9
 
.check_more5:
dec [eax + TCP_SOCKET.timer_persist]
jnz .check_more6
jnz .loop
test [eax + TCP_SOCKET.timer_flags], timer_flag_persist
jz .check_more6
jz .loop
 
DEBUGF DEBUG_NETWORK_VERBOSE, "socket %x: persist timer expired\n", eax
 
160,33 → 163,14
pop eax
mov [eax + TCP_SOCKET.t_force], 0
 
.check_more6:
dec [eax + TCP_SOCKET.timer_timed_wait]
jnz .loop
test [eax + TCP_SOCKET.timer_flags], timer_flag_wait
jz .loop
jmp .loop
 
DEBUGF DEBUG_NETWORK_VERBOSE, "socket %x: timed wait timer expired\n", eax
endp
 
push [eax + SOCKET.NextPtr]
call TCP_close
pop eax
 
jmp .check_only
 
endp
; eax = socket
 
 
;-----------------------------------------------------------------;
; ;
; TCP_cancel_timers ;
; ;
; IN: eax = socket ;
; ;
; OUT: / ;
; ;
;-----------------------------------------------------------------;
align 4
TCP_cancel_timers:
 
mov [eax + TCP_SOCKET.timer_flags], 0
/kernel/branches/Kolibri-acpi/network/tcp_usreq.inc
17,15 → 17,15
$Revision: 5442 $
 
 
;-----------------------------------------------------------------;
; ;
; TCP_usrclosed ;
; ;
; IN: eax = socket ptr ;
; ;
; OUT: / ;
; ;
;-----------------------------------------------------------------;
;-------------------------
;
; TCP_usrclose
;
; Move connection to next state, based on process close.
;
; IN: eax = socket ptr
;
;-------------------------
align 4
TCP_usrclosed:
 
37,6 → 37,7
jmp ebx
 
.switch:
 
dd .close ; TCPS_CLOSED
dd .close ; TCPS_LISTEN
dd .close ; TCPS_SYN_SENT
49,6 → 50,7
dd .disc ; TCPS_FIN_WAIT_2
dd .disc ; TCPS_TIMED_WAIT
 
 
.close:
mov [eax + TCP_SOCKET.t_state], TCPS_CLOSED
call TCP_close
72,17 → 74,15
ret
 
 
;-----------------------------------------------------------------;
; ;
; TCP_connect ;
; ;
; IN: eax = socket ptr ;
; ;
; OUT: eax = 0 on success ;
; eax = -1 on error ;
; ebx = error code on error ;
; ;
;-----------------------------------------------------------------;
;-------------------------
;
; TCP_connect
;
; IN: eax = socket ptr
; OUT: eax = 0 ok / -1 error
; ebx = error code
;
;-------------------------
align 4
TCP_connect: