Subversion Repositories Kolibri OS

Compare Revisions

Regard whitespace Rev 1513 → Rev 1514

/kernel/branches/net/network/stack.inc
1,6 → 1,6
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; ;;
;; Copyright (C) KolibriOS team 2004-2009. All rights reserved. ;;
;; Copyright (C) KolibriOS team 2004-2010. All rights reserved. ;;
;; Distributed under terms of the GNU General Public License ;;
;; ;;
;; STACK.INC ;;
23,19 → 23,22
__DEBUG_LEVEL__ equ 1 ; this sets the debug level for network part of kernel
 
uglobal
last_1sTick db ?
last_1hsTick dd ?
net_10ms dd ?
net_tmr_count dw ?
endg
 
MAX_NET_DEVICES equ 16
QUEUE_BEFORE_SENDING equ 0 ; 1 or 0 (enable or disable) currently only affects ethernet
 
ETH_QUEUE equ 0 ; 1 = enable / 0 = disable
 
MIN_EPHEMERAL_PORT equ 49152
MAX_EPHEMERAL_PORT equ 61000
 
ETHER equ 1337 ; TODO: find another value for this (how does it work in posix ?)
; Ethernet protocol numbers
ETHER_ARP equ 0x0608
ETHER_IPv4 equ 0x0008 ; Reversed from 0800 for intel
 
;Protocol family
AF_UNSPEC equ 0
AF_UNIX equ 1
AF_INET4 equ 2
46,9 → 49,10
;AF_BRIDGE equ 7
;AF_AAL5 equ 8
;AF_X25 equ 9
;AF_INET6 equ 10
AF_INET6 equ 10
;AF_MAX equ 12
 
; Internet protocol numbers
IP_PROTO_IP equ 0
IP_PROTO_ICMP equ 1
IP_PROTO_TCP equ 6
55,54 → 59,31
IP_PROTO_UDP equ 17
 
; Socket types
SOCK_STREAM = 1
SOCK_DGRAM = 2
SOCK_RAW = 3
SOCK_STREAM equ 1
SOCK_DGRAM equ 2
SOCK_RAW equ 3
 
TCB_LISTEN equ 1
TCB_SYN_SENT equ 2
TCB_SYN_RECEIVED equ 3
TCB_ESTABLISHED equ 4
TCB_FIN_WAIT_1 equ 5
TCB_FIN_WAIT_2 equ 6
TCB_CLOSE_WAIT equ 7
TCB_CLOSING equ 8
TCB_LAST_ACK equ 9
TCB_TIMED_WAIT equ 10
TCB_CLOSED equ 11
; Socket options
SO_ACCEPTCON equ 1
 
TH_FIN equ 1 shl 0
TH_SYN equ 1 shl 1
TH_RST equ 1 shl 2
TH_PUSH equ 1 shl 3
TH_ACK equ 1 shl 4
TH_URG equ 1 shl 5
SOCKET_MAXDATA equ 4096
 
; Network driver types
NET_TYPE_ETH equ 1
NET_TYPE_SLIP equ 2
 
macro inc_INET reg {
 
add byte [reg + 3], 1
adc byte [reg + 2], 0
adc byte [reg + 1], 0
adc byte [reg], 0
virtual at 0
 
}
NET_DEVICE:
.type dd ?
.end:
 
end virtual
 
macro add_INET reg {
add byte [reg + 3], cl
adc byte [reg + 2], ch
adc byte [reg + 1], 0
adc byte [reg], 0
rol ecx, 16
add byte [reg + 1], cl
adc byte [reg], ch
rol ecx, 16
}
 
 
; Exactly as it says..
macro pseudo_random reg {
 
add reg, [esp]
rol reg, 5
xor reg, [timer_ticks]
109,23 → 90,48
imul reg, 214013
xor reg, 0xdeadbeef
rol reg, 9
}
 
pushd reg
mov word [esp], 0x8080 ; kernel heap start addr (os_stack)
xor reg, [esp]
add esp, 4
macro ntohld reg {
 
rol word reg, 8
rol dword reg, 16
rol word reg, 8
 
}
 
macro ntohlw reg {
 
rol word reg, 8
 
}
 
 
include "queue.inc"
 
include "ethernet.inc"
;include "slip.inc"
 
include "ARP.inc"
include "IPv4.inc"
include "ethernet.inc"
include "socket.inc"
 
include "icmp.inc"
include "udp.inc"
include "tcp.inc"
include "udp.inc"
include "icmp.inc"
 
include "socket.inc"
 
 
 
align 4
uglobal
 
NET_RUNNING dd ?
NET_DRV_LIST rd MAX_NET_DEVICES
 
endg
 
 
;-----------------------------------------------------------------
;
; stack_init
139,28 → 145,37
align 4
stack_init:
 
; Init the network drivers list
 
xor eax, eax
mov edi, NET_RUNNING
mov ecx, MAX_NET_DEVICES + 1
rep stosd
 
; Call other init procedures
 
call ETH_init
; call SLIP_init
 
call IPv4_init
call ICMP_init
 
call ARP_init
call UDP_init
call TCP_init
call ICMP_init
 
call socket_init
 
mov al, 0 ; set up 1s timer
out 0x70, al
in al, 0x71
mov [last_1sTick], al
mov [net_tmr_count], 0
 
ret
 
 
 
;-----------------------------------------------------------------
;
; stack_handler
;
; This function calls all network init procedures
; This function is called in kernel loop
;
; IN: /
; OUT: /
169,43 → 184,232
align 4
stack_handler:
 
cmp [ETH_RUNNING], 0
cmp [NET_RUNNING], 0
je .exit
 
; Test for 10ms tick
mov eax, [timer_ticks]
cmp eax, [last_1hsTick]
cmp eax, [net_10ms]
je .exit
mov [net_10ms], eax
 
mov [last_1hsTick], eax
 
call ETH_handler ; handle all queued ethernet packets
if QUEUE_BEFORE_SENDING
if ETH_QUEUE
call ETH_handler
call ETH_send_queued
end if
call TCP_send_queued
call TCP_10ms
 
.sec_tick:
inc [net_tmr_count]
cmp [net_tmr_count], 50
je .500ms
cmp [net_tmr_count], 100
jne .exit
 
; Test for 1 second tick
mov al, 0
out 0x70, al
in al, 0x71
cmp al, [last_1sTick]
je .exit
 
mov [last_1sTick], al
 
call ARP_decrease_entry_ttls
call IPv4_decrease_fragment_ttls
call TCP_decrease_socket_ttls
call TCP_timer_1000ms
 
mov [net_tmr_count], 0
 
.500ms:
call TCP_500ms
 
.exit:
ret
 
 
 
;-----------------------------------------------------------------
;
; NET_Add_Device:
;
; This function is called by the network drivers,
; to register each running NIC to the kernel
;
; IN: Pointer to device structure in ebx
; OUT: Device num in eax, -1 on error
;
;-----------------------------------------------------------------
align 4
NET_add_device:
 
DEBUGF 1,"NET_Add_Device: %x\n", ebx
 
mov eax, [NET_RUNNING]
cmp eax, MAX_NET_DEVICES
jge .error
 
;----------------------------------
; Check if device is already listed
mov eax, ebx
mov ecx, MAX_NET_DEVICES ; We need to check whole list because a device may be removed without re-organizing list
mov edi, NET_DRV_LIST
 
repne scasd ; See if device is already in the list
jz .error
 
;----------------------------
; Find empty slot in the list
xor eax, eax
mov ecx, MAX_NET_DEVICES
mov edi, NET_DRV_LIST
 
repne scasd
jnz .error
 
sub edi, 4
 
cmp [ebx + NET_DEVICE.type], NET_TYPE_ETH
je .ethernet
 
cmp [ebx + NET_DEVICE.type], NET_TYPE_SLIP
je .slip
 
DEBUGF 1,"Unknown network device type: %u\n", [ebx + NET_DEVICE.type]
jmp .error
 
.ethernet:
DEBUGF 1,"Trying to add an ethernet driver\n"
 
inc [ETH_RUNNING] ; Indicate that one more ethernet device is up and running
jmp .add_it
 
.slip:
DEBUGF 1,"Trying to add a slip driver\n"
;;;;
jmp .error
 
 
.add_it:
 
;-----------------------------
; Add device to the found slot
mov [edi], ebx ; add device to list
 
sub edi, NET_DRV_LIST ; Calculate device number in eax
mov eax, edi ;
shr eax, 2
 
inc [NET_RUNNING] ; Indicate that one more network device is up and running
 
DEBUGF 1,"Device number: %u\n",eax
ret
 
.error:
or eax, -1
DEBUGF 2,"Adding network device failed\n"
ret
 
 
 
;-----------------------------------------------------------------
;
; NET_Remove_Device:
;
; This function is called by etwork drivers,
; to unregister network devices from the kernel
;
; IN: Pointer to device structure in ebx
; OUT: eax: -1 on error
;
;-----------------------------------------------------------------
align 4
NET_remove_device:
 
cmp [NET_RUNNING], 0
je .error
 
;----------------------------
; Find the driver in the list
 
mov eax, ebx
mov ecx, MAX_NET_DEVICES
mov edi, NET_DRV_LIST
 
repne scasd
jnz .error
 
;------------------------
; Remove it from the list
 
xor eax, eax
mov dword [edi-4], eax
 
dec [NET_RUNNING]
ret
 
.error:
or eax, -1
ret
 
 
 
;-----------------------------------------------------------------
;
; NET_ptr_to_num
;
; IN: ebx = ptr to device struct
; OUT: edi = -1 on error, device number otherwise
;
;-----------------------------------------------------------------
align 4
NET_ptr_to_num:
push ecx
 
mov ecx, MAX_NET_DEVICES
mov edi, NET_DRV_LIST
 
.loop:
cmp ebx, [edi]
jz .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
 
 
 
 
;--------------------------
;
; 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
;
; This is the first of two functions needed to calculate a checksum.
333,7 → 537,7
cmp ebx, -1
jne @f
 
mov eax, [ETH_RUNNING]
mov eax, [NET_RUNNING]
jmp .return
 
@@:
344,12 → 548,12
and esi, 0x0000ff00
shr esi, 6
 
cmp dword [esi + ETH_DRV_LIST], 0 ; check if driver is running
cmp dword [esi + NET_DRV_LIST], 0 ; check if driver is running
je .doesnt_exist
 
test bl, bl ; 0 = Get device type (ethernet/token ring/...)
jnz @f
; todo
 
xor eax, eax
jmp .return
 
358,7 → 562,7
dec bl ; 1 = Get device name
jnz @f
 
mov esi, [esi + ETH_DRV_LIST]
mov esi, [esi + NET_DRV_LIST]
mov esi, [esi + ETH_DEVICE.name]
mov edi, ecx
 
373,7 → 577,7
dec bl ; 2 = Reset the device
jnz @f
 
mov esi, [esi + ETH_DRV_LIST]
mov esi, [esi + NET_DRV_LIST]
call [esi + ETH_DEVICE.reset]
jmp .return
 
382,7 → 586,7
dec bl ; 3 = Stop driver for this device
jnz @f
 
mov esi, [esi + ETH_DRV_LIST]
mov esi, [esi + NET_DRV_LIST]
call [esi + ETH_DEVICE.unload]
jmp .return
 
407,7 → 611,7
 
;----------------------------------------------------------------
;
; System Function To work with Protocols (75)
; System function to work with protocols (75)
;
;----------------------------------------------------------------
align 4
417,8 → 621,8
 
mov esi, ebx
and esi, 0x0000ff00
shr esi, 6
cmp dword [esi + ETH_DRV_LIST], 0 ; check if driver is running TODO: check other lists too
shr esi, 6 ; now we have the device num * 4 in esi
cmp dword [esi + NET_DRV_LIST], 0 ; check if driver is running
je .doesnt_exist
 
push .return ; return address (we will be using jumps instead of calls)
441,7 → 645,7
cmp ax , ETHER_ARP
je ARP_API
 
cmp ax , ETHER
cmp ax , 1337
je ETH_API
 
add esp, 4 ; if we reached here, no function was called, so we need to balance stack