Subversion Repositories Kolibri OS

Compare Revisions

Regard whitespace Rev 1518 → Rev 1519

/kernel/branches/net/network/ARP.inc
130,7 → 130,7
; else
; destination is remote, so pass to gateway
 
xor edx, edx ; TODO: find device num in edx
xor edx, edx ;;; TODO: find device num in edx
 
mov ebx, [IP_LIST+edx]
and ebx, [SUBNET_LIST+edx]
274,7 → 274,8
DEBUGF 1,"ARP Packet for device %x created successfully\n", ebx
 
push edx ecx
jmp NET_send
call [ebx + NET_DEVICE.transmit]
ret
 
.exit:
add esp, 8
572,7 → 573,8
 
DEBUGF 1,"ARP_Handler - Sending reply \n"
 
jmp NET_send ; And send it!
call [ebx + NET_DEVICE.transmit]
ret
 
.exit:
call kernel_free
/kernel/branches/net/network/IPv4.inc
172,10 → 172,10
cmp [edx + IPv4_Packet.DestinationAddress], -1
je .ip_ok
 
; ; maybe it's a multicast then
;
; mov eax, [edx + IPv4_Packet.DestinationAddress]
; and eax, 0xff000000
; maybe it's a multicast then
 
mov eax, [edx + IPv4_Packet.DestinationAddress]
and eax, 0xff000000
; cmp eax, 224 shl 24
; je .ip_ok
 
/kernel/branches/net/network/ethernet.inc
16,8 → 16,6
 
$Revision$
 
ETH_QUEUE_SIZE equ 16
 
struct ETH_FRAME
.DstMAC dp ? ; destination MAC-address
.SrcMAC dp ? ; source MAC-address
28,20 → 26,14
virtual at NET_DEVICE.end
 
ETH_DEVICE:
.unload dd ?
.reset dd ?
.transmit dd ?
.set_MAC dd ?
.get_MAC dd ?
 
.set_mode dd ?
.get_mode dd ?
 
.bytes_tx dq ?
.bytes_rx dq ?
.packets_tx dd ?
.packets_rx dd ?
.set_MAC dd ?
.get_MAC dd ?
 
.mode dd ?
.name dd ?
.mac dp ?
 
end virtual
108,6 → 100,9
cmp ax, ETHER_ARP
je ARP_handler
 
; cmp ax, ETHER_PPP_DISCOVERY
; je PPPOE_discovery
 
DEBUGF 2,"Unknown ethernet packet type %x\n", ax
 
.dump:
138,7 → 133,10
 
DEBUGF 1,"Creating Ethernet Packet (size=%u): \n", ecx
 
cmp ecx, 1500 ;;;
push esi
mov esi, [NET_DRV_LIST] ;;; TODO: FIXME
cmp ecx, [esi + NET_DEVICE.mtu]
pop esi
jg .exit
 
push ecx di eax ebx edx
171,7 → 169,7
mov ebx, [NET_DRV_LIST + ebx]
 
cmp edx, 46 + ETH_FRAME.Data ; If data size is less then 46, add padding bytes
jg .continue
jge .continue
mov edx, 46 + ETH_FRAME.Data
.continue:
 
240,23 → 238,23
ret
 
.packets_tx:
mov eax, dword [eax + ETH_DEVICE.packets_tx]
mov eax, dword [eax + NET_DEVICE.packets_tx]
 
ret
 
.packets_rx:
mov eax, dword [eax + ETH_DEVICE.packets_rx]
mov eax, dword [eax + NET_DEVICE.packets_rx]
ret
 
.bytes_tx:
mov ebx, dword [eax + ETH_DEVICE.bytes_tx + 4]
mov eax, dword [eax + ETH_DEVICE.bytes_tx]
mov ebx, dword [eax + NET_DEVICE.bytes_tx + 4]
mov eax, dword [eax + NET_DEVICE.bytes_tx]
mov [esp+20+4], ebx ; TODO: fix this ugly code
ret
 
.bytes_rx:
mov ebx, dword [eax + ETH_DEVICE.bytes_rx + 4]
mov eax, dword [eax + ETH_DEVICE.bytes_rx]
mov ebx, dword [eax + NET_DEVICE.bytes_rx + 4]
mov eax, dword [eax + NET_DEVICE.bytes_rx]
mov [esp+20+4], ebx ; TODO: fix this ugly code
ret
 
270,8 → 268,7
.write_mac:
push ecx
push dx
mov eax, [eax + ETH_DEVICE.set_MAC]
call eax
call [eax + ETH_DEVICE.set_MAC]
ret
 
.in_queue:
/kernel/branches/net/network/icmp.inc
209,8 → 209,8
pop ecx edx ebx
mov word [edx + ICMP_Packet.Checksum], ax
 
jmp NET_send ; Send the reply
; and return to caller of this proc
call [ebx + NET_DEVICE.transmit]
ret
 
 
 
251,7 → 251,7
add esp, 4
sub edx, esi
mov edi, edx
;;; jmp SOCKET_input
jmp SOCKET_input
 
.dump:
DEBUGF 1,"ICMP_Handler - dumping\n"
264,11 → 264,9
 
;-----------------------------------------------------------------
;
; Note: ICMP only works on top of IP protocol :)
; ICMP_output
;
; inputs:
;
; eax = dest ip
; IN: eax = dest ip
; ebx = source ip
; ecx = data length
; dh = type
281,7 → 279,7
align 4
ICMP_output:
 
DEBUGF 1,"Create ICMP Packet\n"
DEBUGF 1,"Creating ICMP Packet\n"
 
push esi edi edx
 
320,11 → 318,10
rep movsb
 
sub edi, edx ;;; TODO: find a better way to remember start of packet
mov ecx, [ebx + ETH_DEVICE.transmit]
push edx edi ecx
push edx edi
DEBUGF 1,"Sending ICMP Packet\n"
ret ; Send the packet (create_packet routine outputs pointer to routine to send packet in eax)
 
call [ebx + NET_DEVICE.transmit]
ret
.exit:
DEBUGF 1,"Creating ICMP Packet failed\n"
add esp, 3*4
/kernel/branches/net/network/socket.inc
74,7 → 74,6
.OrigRemotePort dw ? ; original remote port (used to reset to LISTEN state)
 
.t_state dd ? ; TCB state
.t_timer dd ? ; TCB timer (seconds)
.t_rxtshift dd ?
.t_rxtcur dd ?
.t_dupacks dd ?
144,6 → 143,16
.ts_recent_age dd ?
.last_ack_sent dd ?
 
 
;-------
; Timers
 
.timer_retransmission dw ? ; rexmt
.timer_ack dw ?
.timer_persist dw ?
.timer_keepalive dw ? ; keepalive/syn timeout
.timer_timed_wait dw ? ; also used as 2msl timer
 
.end:
end virtual
 
335,7 → 344,7
jz s_error
 
.got_port:
DEBUGF 1,"using local port: %u", bx
DEBUGF 1,"using local port: %u\n", bx
mov word [eax + UDP_SOCKET.LocalPort], bx
 
mov ebx, dword [edx + 4]
391,7 → 400,7
mov bx , word [edx + 2]
mov word [eax + UDP_SOCKET.RemotePort], bx
mov [eax + UDP_SOCKET.firstpacket], 0
DEBUGF 1,"remote port: %u ",bx
DEBUGF 1,"remote port: %u\n",bx
 
mov ebx, dword [edx + 4]
mov dword [eax + IP_SOCKET.RemoteIP], ebx
408,6 → 417,8
add [TCP_sequence_num], 6400
mov [eax + TCP_SOCKET.ISS], ebx
 
mov [eax + TCP_SOCKET.timer_keepalive], 120 ; 120*630ms => 75,6 seconds
 
lea ebx, [eax + SOCKET.lock]
call wait_mutex
 
417,7 → 428,7
 
mov bx , word [edx + 2]
mov [eax + TCP_SOCKET.RemotePort], bx
DEBUGF 1,"remote port: %u ",bx
DEBUGF 1,"remote port: %u\n", bx
 
mov ebx, dword [edx + 4]
mov [eax + IP_SOCKET.RemoteIP], ebx
435,6 → 446,8
call SOCKET_find_port
@@:
 
DEBUGF 1,"remote port: %u\n", [eax + TCP_SOCKET.LocalPort]:2
 
; mov [eax + TCP_SOCKET.t_state], TCB_SYN_SENT
call TCP_output
 
/kernel/branches/net/network/stack.inc
37,6 → 37,8
; Ethernet protocol numbers
ETHER_ARP equ 0x0608
ETHER_IPv4 equ 0x0008 ; Reversed from 0800 for intel
ETHER_PPP_DISCOVERY equ 0x6388
ETHER_PPP_SESSION equ 0x6488
 
;Protocol family
AF_UNSPEC equ 0
76,7 → 78,20
virtual at 0
 
NET_DEVICE:
.type dd ?
 
.type dd ? ; Type field
.mtu dd ? ; Maximal Transmission Unit
.name dd ? ; Ptr to 0 terminated string
 
.unload dd ? ; Ptrs to driver functions
.reset dd ? ;
.transmit dd ? ;
 
.bytes_tx dq ? ; Statistics, updated by the driver
.bytes_rx dq ? ;
.packets_tx dd ? ;
.packets_rx dd ? ;
 
.end:
 
end virtual
193,27 → 208,18
je .exit
mov [net_10ms], eax
 
if ETH_QUEUE
call ETH_handler
call ETH_send_queued
end if
call TCP_10ms
test [net_10ms], 0x0f ; 160ms
jnz .exit
 
inc [net_tmr_count]
cmp [net_tmr_count], 50
je .500ms
cmp [net_tmr_count], 100
jne .exit
; call TCP_timer_160ms
 
test [net_10ms], 0x3f ; 640ms
jnz .exit
 
; call TCP_timer_640ms
call ARP_decrease_entry_ttls
call IPv4_decrease_fragment_ttls
call TCP_timer_1000ms
 
mov [net_tmr_count], 0
 
.500ms:
call TCP_500ms
 
.exit:
ret
 
380,34 → 386,6
pop ecx
ret
 
 
 
 
;--------------------------
;
; NET_send
;
; IN: ebx = ptr to device struct
; [esp] = data ptr
; [esp + 4] = data size
;
; OUT: /
;
;--------------------------
align 4
NET_send:
 
call [ebx + ETH_DEVICE.transmit] ;;;;
 
;;; TODO:check if packet was sent ok
 
call kernel_free
add esp, 4
ret
 
 
 
 
;-----------------------------------------------------------------
;
; checksum_1
563,7 → 541,7
jnz @f
 
mov esi, [esi + NET_DRV_LIST]
mov esi, [esi + ETH_DEVICE.name]
mov esi, [esi + NET_DEVICE.name]
mov edi, ecx
 
mov ecx, 64 ; max length
578,7 → 556,7
jnz @f
 
mov esi, [esi + NET_DRV_LIST]
call [esi + ETH_DEVICE.reset]
call [esi + NET_DEVICE.reset]
jmp .return
 
@@:
587,7 → 565,7
jnz @f
 
mov esi, [esi + NET_DRV_LIST]
call [esi + ETH_DEVICE.unload]
call [esi + NET_DEVICE.unload]
jmp .return
 
@@:
645,7 → 623,7
cmp ax , ETHER_ARP
je ARP_API
 
cmp ax , 1337
cmp ax , 1337 ;;;;;
je ETH_API
 
add esp, 4 ; if we reached here, no function was called, so we need to balance stack
/kernel/branches/net/network/tcp.inc
58,6 → 58,22
TCP_OPT_WINDOW equ 3 ; window scale
TCP_OPT_TIMESTAMP equ 8
 
; Fundamental timer values
TCP_time_MSL equ 47 ; max segment lifetime (30s)
TCP_time_re_min equ 2 ; min retransmission (1,28s)
TCP_time_re_max equ 100 ; max retransmission (64s)
TCP_time_pers_min equ 8 ; min persist (5,12s)
TCP_time_pers_max equ 94 ; max persist (60,16s)
TCP_time_keep_init equ 118 ; connectione stablishment (75,52s)
TCP_time_keep_idle equ 4608 ; idle time before 1st probe (2h)
TCP_time_keep_interval equ 118 ; between probes when no response (75,52s)
TCP_time_rtt_default equ 5 ; default Round Trip Time (3,2s)
 
; timer constants
TCP_max_rxtshift equ 12 ; max retransmissions waiting for ACK
TCP_max_keepcnt equ 8 ; max keepalive probes
 
 
struct TCP_segment
.SourcePort dw ?
.DestinationPort dw ?
118,24 → 134,16
ret
 
 
;-----------------------------------------------------------------
;----------------------
;
; decrease socket ttls
;
; IN: /
; OUT: /
;
; destroys: eax
;
;-----------------------------------------------------------------
;----------------------
align 4
TCP_timer_1000ms:
; scan through all the active TCP sockets, decrementing active timers
TCP_timer_160ms:
 
mov eax, net_sockets
.loop:
mov eax, [eax + SOCKET.NextPtr]
.check_only:
or eax, eax
jz .exit
 
142,62 → 150,80
cmp [eax + SOCKET.Type], IP_PROTO_TCP
jne .loop
 
cmp [eax + TCP_SOCKET.t_timer], 0
jne .decrement_tcb
;;;;;; cmp [eax + TCP_SOCKET.wndsizeTimer], 0
jne .decrement_wnd
jmp .loop
 
.decrement_tcb:
; decrement it, delete socket if TCB timer = 0 & socket in timewait state
dec [eax + TCP_SOCKET.t_timer]
dec [eax + TCP_SOCKET.timer_ack]
jnz .loop
 
cmp [eax + TCP_SOCKET.t_state], TCB_TIMED_WAIT
jne .loop
DEBUGF 1,"TCP ack for socket %x expired, time to piggyback!\n", eax
 
push [eax + SOCKET.NextPtr]
call SOCKET_free
push eax
call TCP_respond
pop eax
jmp .check_only
 
.decrement_wnd:
;;;;;; dec [eax + TCP_SOCKET.wndsizeTimer]
jmp .loop
 
.exit:
 
ret
 
 
 
;----------------------
;-----------------------------------------------------------------
;
; TCP_500ms
;
;----------------------
;-----------------------------------------------------------------
align 4
TCP_500ms:
TCP_timer_640ms:
 
; Update TCP sequence number
 
add [TCP_sequence_num], 64000
 
ret
; scan through all the active TCP sockets, decrementing ALL timers
; timers do not have the chance to wrap because of the keepalive timer will kill the socket when it expires
 
mov eax, net_sockets
.loop:
mov eax, [eax + SOCKET.NextPtr]
.check_only:
or eax, eax
jz .exit
 
cmp [eax + SOCKET.Type], IP_PROTO_TCP
jne .loop
 
;----------------------
;
; TCP_10ms
;
;----------------------
align 4
TCP_10ms:
dec [eax + TCP_SOCKET.timer_retransmission]
jnz .check_more2
 
; todo: decrease timers
DEBUGF 1,"socket %x: Retransmission timer expired\n", eax
 
ret
push eax
call TCP_output
pop eax
 
.check_more2:
dec [eax + TCP_SOCKET.timer_keepalive]
jnz .check_more3
 
DEBUGF 1,"socket %x: Keepalive expired\n", eax
 
;;; TODO: check socket state and handle accordingly
 
.check_more3:
dec [eax + TCP_SOCKET.timer_timed_wait]
jnz .check_more5
 
DEBUGF 1,"socket %x: 2MSL timer expired\n", eax
 
.check_more5:
dec [eax + TCP_SOCKET.timer_persist]
jnz .loop
 
DEBUGF 1,"socket %x: persist timer expired\n", eax
 
jmp .loop
.exit:
ret
 
 
;-----------------------------------------------------------------
;
; TCP_input:
374,8 → 400,9
;-------------------------------------
; Reset idle timer and keepalive timer
 
;;;; TODO: idle timer?
 
; TODO
mov [ebx + TCP_SOCKET.timer_keepalive], TCP_time_keep_interval
 
;-----------------------------------------
; Process TCP options if not in LISTEN state
475,14 → 502,15
; Delete acknowledged bytes from send buffer
 
; Stop retransmit timer
mov [ebx + TCP_SOCKET.timer_ack], 0
 
; Awaken waiting processes
mov eax, ebx
call SOCKET_notify_owner
 
; Generate more output
call TCP_output
 
 
 
 
jmp .drop
 
 
518,9 → 546,10
add [ebx + TCP_SOCKET.RCV_NXT], ecx
 
; Add the data to the socket buffer
mov eax, ebx
;;; mov...
call SOCKET_input
 
; The receiving process is awakened (by sorwakeup).
 
; The delayed-ACK flag is set and the input processing is complete.
 
jmp .drop
679,9 → 708,9
jle @f
mov [ebx + TCP_SOCKET.SND_NXT], eax
 
mov [ebx + TCP_SOCKET.timer_keepalive], TCP_time_keep_interval
mov [ebx + TCP_SOCKET.timer_retransmission], 0
 
; TODO: turn off retransmission timer
 
mov eax, [edx + TCP_segment.SequenceNumber]
mov [ebx + TCP_SOCKET.IRS], eax
 
937,18 → 966,6
jg .ack_dup
jl .ack_nodup
 
; dd .ack_nodup ;TCB_CLOSED
; dd .ack_nodup ;TCB_LISTEN
; dd .ack_nodup ;TCB_SYN_SENT
; dd .ack_syn_rcvd ;TCB_SYN_RECEIVED
; dd .ack_dup ;TCB_ESTABLISHED
; dd .ack_dup ;TCB_CLOSE_WAIT
; dd .ack_dup ;TCB_FIN_WAIT_1
; dd .ack_dup ;TCB_CLOSING
; dd .ack_dup ;TCB_LAST_ACK
; dd .ack_dup ;TCB_FIN_WAIT_2
; dd .ack_dup ;TCB_TIMED_WAIT
 
;;;;;
 
.ack_dup:
960,7 → 977,7
;;;; 887
 
;-------------------------------------------------
; If the congestion window was infalted to account
; If the congestion window was inflated to account
; for the other side's cached packets, retrace it
 
;;;; 888 - 902
971,7 → 988,15
 
;;;;; 903 - 926
 
mov [ebx + TCP_SOCKET.timer_retransmission], 0
 
mov eax, [ebx + TCP_SOCKET.SND_MAX]
cmp eax, [edx + TCP_segment.AckNumber]
je .all_outstanding
mov [ebx + TCP_SOCKET.timer_retransmission], 120 ;;;; TODO: correct this value
.all_outstanding:
 
 
;-------------------------------------------
; Open congestion window in response to ACKs
 
1614,7 → 1639,7
 
.enter_persist:
 
DEBUGF 1,"Entering pesist state\n"
DEBUGF 1,"Entering persist state\n"
 
 
 
1748,7 → 1773,7
;;;; jz .fail
 
push edx eax
call NET_send
call [ebx + NET_DEVICE.transmit]
ret
 
;----------------
1831,12 → 1856,9
 
 
DEBUGF 1,"Sending TCP Packet to device %x\n", ebx
mov esi, [ebx + ETH_DEVICE.transmit]
 
call [ebx + NET_DEVICE.transmit]
ret
 
 
 
;-------------------------
;
; TCP_outflags
1902,11 → 1924,14
 
;---------------------------------------
;
; TCP_respond
; TCP_ack
;
; The easy way to send a RST/ACK segment
; The easy way to send an ACK/RST/keepalive segment
;
; IN: eax = socket ptr
; -or-
; edx = packet ptr (eax must be 0)
; cl = flags
;
; OUT: /
;
1916,10 → 1941,117
 
DEBUGF 1,"TCP_respond\n"
 
;---------------------
; Create the IP packet
 
push cx eax edx
mov ebx, [eax + IP_SOCKET.LocalIP]
mov eax, [eax + IP_SOCKET.RemoteIP]
mov ecx, TCP_segment.Data
mov di , IP_PROTO_TCP
call IPv4_create_packet
test edi, edi
jz .error
 
;---------------------------
; Now fill in the TCP header
 
pop ecx
pop esi
 
test esi, esi
; jz
 
 
push edx eax
 
push dword .checksum
je .use_segment
jmp .use_socket
 
;---------------------
; Fill in the checksum
 
.checksum:
 
push [esi + IP_SOCKET.LocalIP]
push [esi + IP_SOCKET.RemoteIP]
lea esi, [edi - 20]
xor ecx, ecx
call TCP_checksum
 
;--------------------
; And send the segment
 
call [ebx + NET_DEVICE.transmit]
ret
 
.error:
DEBUGF 1,"TCP_ack failed\n"
add esp, 4
 
ret
 
;---------------------------------------------------
; Fill in the TCP header by using a received segment
 
.use_segment:
 
mov ax, [esi + TCP_segment.DestinationPort]
rol ax, 8
stosw
mov ax, [esi + TCP_segment.SourcePort]
rol ax, 8
stosw
mov eax, [esi + TCP_segment.AckNumber]
bswap eax
stosd
xor eax, eax
stosd
mov al, 0x50 ; Dataoffset: 20 bytes
stosb
mov al, cl
stosb
mov ax, 1280
rol ax, 8
stosw ; window
xor eax, eax
stosd ; checksum + urgentpointer
 
ret
 
 
;-----------------------------------------------
; Fill in the TCP header by using the socket ptr
 
.use_socket:
 
mov ax, [esi + TCP_SOCKET.LocalPort]
rol ax, 8
stosw
mov ax, [esi + TCP_SOCKET.RemotePort]
rol ax, 8
stosw
mov eax, [esi + TCP_SOCKET.SND_NXT]
bswap eax
stosd
mov eax, [esi + TCP_SOCKET.RCV_NXT]
bswap eax
stosd
mov al, 0x50 ; Dataoffset: 20 bytes
stosb
mov al, cl
stosb
mov ax, [esi + TCP_SOCKET.RCV_WND]
rol ax, 8
stosw ; window
xor eax, eax
stosd ; checksum + urgentpointer
 
ret
 
 
 
;-----------------------------------------------------------------
;
; TCP_checksum
/kernel/branches/net/network/udp.inc
252,8 → 252,8
 
DEBUGF 1,"Sending UDP Packet to device %x\n", ebx
 
jmp NET_send
 
call [ebx + NET_DEVICE.transmit]
ret
.fail:
add esp, 8+8
ret