- globalisation of network driver functions

(Replaced EthRegDev with NetRegDev)
- rewrite/cleanup of socket.inc
- started rewrite of tcp.inc 
- port numbers in application are not byte-swapped anymore
- many more fixes and changes

- TCP does not work but UDP/IP/ICMP/ARP (partly) work.. (as before)



git-svn-id: svn://kolibrios.org@1514 a494cfbc-eb01-0410-851d-a64ba20cac60
This commit is contained in:
hidnplayr 2010-07-11 23:13:12 +00:00
parent 321a58ac0f
commit 6a1d621671
26 changed files with 6368 additions and 5705 deletions

View File

@ -157,6 +157,8 @@ draw_window:
mcall 12, 1 ; start of draw
mcall 0, dword [Form], dword [Form + 4], 0x13ffffff, 0x805080d0, title
mcall 8, 136 shl 16 + 100, 35 shl 16 + 18, 4, 0x00007f00 ; SLIP
call Get_PCI_Info ; get pci version and last bus, scan for and draw each pci device
cmp edx, 20 shl 16 + 110

View File

@ -689,7 +689,7 @@ lock xadd [DNSrequestID], eax ; atomically increment ID, get old value
push 0
push 0 ; sin_zero
push esi ; sin_addr
push AF_INET + (53 shl 24)
push AF_INET + (53 shl 16)
; sin_family and sin_port in network byte order
; 8c. Connect.
mcall 74, 4, , esp, sizeof.sockaddr_in

View File

@ -13,7 +13,7 @@ use32
include '../macros.inc'
purge mov,add,sub
include '../proc32.inc'
include 'dll.inc'
include '../dll.inc'
include '../network_lib/network.inc'

View File

@ -194,7 +194,7 @@ str7 db 'Got data!',10,10,0
sockaddr1:
dw AF_INET4
.port dw 23 shl 8
.port dw 23
.ip dd 0
rb 10

View File

@ -1,31 +1,35 @@
use32
org 0x0
db 'MENUET01'
dd 1, START, I_END, IM_END+0x1000, IM_END+0x1000, 0, 0
dd 0x1
dd START
dd I_END
dd IM_END
dd IM_END
dd 0, 0
include '../proc32.inc'
include '../macros.inc'
include '../dll.inc'
include '../libio.inc'
include '../../../../../programs/develop/libraries/box_lib/trunk/box_lib.mac'
include '../dll.inc'
include 'editbox_ex.mac'
include '../network.inc'
filebuffer_size equ 4*4096 ; 16kb (dont try to change it yet..)
TIMEOUT equ 500
TIMEOUT equ 100
buffer_len equ 1500
AF_INET4 equ 2
IP_PROTO_UDP equ 17
opcode_rrq equ 1 shl 8
opcode_wrq equ 2 shl 8
opcode_data equ 3 shl 8
opcode_ack equ 4 shl 8
opcode_error equ 5 shl 8
opcode_rrq equ 1
opcode_wrq equ 2
opcode_data equ 3
opcode_ack equ 4
opcode_error equ 5
; read/write request packet
;
@ -51,14 +55,14 @@ opcode_error equ 5 shl 8
; error packet
;
; 2 bytes 2 bytes string 1 byte
; -----------------------------------------
; ----------------------------------------
; | Opcode | ErrorCode | ErrMsg | 0 |
; -----------------------------------------
; ----------------------------------------
START:
;; mcall 68, 11
mcall 68, 11
stdcall dll.Load, @IMPORT
or eax, eax
@ -185,11 +189,11 @@ draw_window:
mcall 4,350*65536+137, 0x80000000, str_kb_s
; mcall 47,1 shl 31 + 7 shl 16 + 1,kbps,305*65536+137,0x00000000
mcall 47,1 shl 31 + 7 shl 16 + 1,kbps,305*65536+137,0x00000000
mcall 4,20*65536+137, 0x80000000, [status]
mcall 4,50*65536+137, 0x80000000, str_complete
; mcall 47,1 shl 31 + 3 shl 16 + 1,done,25*65536+137,0x00000000
mcall 47,1 shl 31 + 3 shl 16 + 1,done,25*65536+137,0x00000000
mcall 12,2
@ -209,30 +213,19 @@ start_transfer:
push esp ; fourth parameter
push 0 ; third parameter
push 0 ; second parameter
push SRV ; first parameter
push dword SRV ; first parameter
call [getaddrinfo]
pop esi ; now we will have pointer to result in esi
pop esi
; test for error
test eax, eax
jnz still
mov esi, [esi + addrinfo.ai_addr]
mov esi, [esi]
mov esi, [esi + sockaddr_in.sin_addr]
mov dword [IP], esi
stdcall mem.Alloc, buffer_len
test eax, eax
jz stop_transfer
mov [packetbuff], eax
invoke file_open, local_addr, O_READ + O_WRITE + O_CREATE
cmp eax, 32
jb stop_transfer
mov [fh], eax
mcall socket, AF_INET4, IP_PROTO_UDP, 0 ; socket_open
cmp eax, -1
je still
@ -244,8 +237,8 @@ start_transfer:
je still
mov word [I_END], opcode_rrq
cmp [option_group2],op3 ; method = get?
jz @f
cmp [option_group2],op3
je @f
mov word [I_END], opcode_wrq
@@:
@ -253,7 +246,7 @@ start_transfer:
mov edi, remote_addr
mov ecx, 250
repnz scasb
sub edi, remote_addr
sub edi, remote_addr-1
mov ecx, edi
mov edi, I_END+2
mov esi, remote_addr
@ -283,211 +276,168 @@ start_transfer:
mov esi, edi
mcall send, [socketnum], I_END
mov [last_ack], 0
; mcall 26, 9
; mov [last_time], eax
mov [status], str_transfering
call draw_window
mcall 40, 10000101b
cmp [option_group2],op3 ; method = get?
jnz send_data_loop
mov [last_ack], 0
invoke file_truncate, [fh]
receive_data_loop:
mcall 23, TIMEOUT
dec eax
jz .redraw
jz .red
dec eax
dec eax
jz .btn
jz .key
mcall recv, [socketnum], [packetbuff], buffer_len ; receive data
mov esi, [packetbuff]
cmp word[esi], opcode_data
mcall recv, [socketnum], buffer, buffer_len, 0 ; receive data
cmp word[buffer], opcode_data
jne .error
mov bx, [last_ack]
inc bx
rol bx, 8
cmp word [esi + 2], bx
cmp word [buffer + 2], bx
jne .packet_got_lost
inc [last_ack]
; now, we need to store the data
add esi, 4
sub eax, 4
mov ecx, eax
invoke file_write, [fh], esi ,ecx
cmp ecx, 512 ; full data packet?
jge .continue
cmp eax, 4+512
je .continue
; last packet, or something else
mov [status], str_success
.kill_xfer:
invoke file_close, [fh]
mcall close, [socketnum]
jmp stop_transfer
.error:
cmp word[esi], opcode_error
je .decode_error
jmp .continue
.packet_got_lost:
.continue:
; mcall 26, 9
; mov ebx, [last_time]
; mov [last_time], eax
; xor edx, edx
; sub eax, ebx
; xchg eax, ecx
; div ecx
; mov [kbps], eax
; mcall 47,1 shl 31 + 7 shl 16 + 1,kbps,305*65536+137,0x40000000, 0x00ffffff
mov word[buffer], opcode_ack ; send ack
mov ax, [last_ack]
rol ax, 8
mov word [buffer+2], ax
mcall send, [socketnum], buffer, 4, 0
jmp receive_data_loop
.red:
.btn:
mcall 17
jmp .kill_xfer
.redraw:
call draw_window
jmp receive_data_loop
.decode_error:
movzx esi, word[esi + 2]
cmp esi, 7
cmovg esi, [zero]
.key:
mcall 2
cmp ah, 2
jz exit
; close socket ?
jmp receive_data_loop
mov esi, dword [4*esi + error_crosslist]
mov [status], esi
jmp .kill_xfer
;--------------------------------
send_data_loop:
send_:
mov word[buffer], opcode_data
invoke file_open, local_addr, O_READ
or eax, eax
jz .exit
mov [fh], eax
stdcall mem.Alloc, filebuffer_size
or eax, eax
jz .exit
mov [fb], eax
mov [last_ack], 0
mov [fo], 0
.read_chunk:
inc [last_ack]
mov ax, [last_ack]
xchg al, ah
mov word[buffer+2], ax
invoke file_read, [fh], buffer + 4, 512
invoke file_seek, [fh], [fo], SEEK_END
cmp eax, -1
je .kill_xfer
je .exit
invoke file_read, [fh], [fb], filebuffer_size
cmp eax, -1
je .exit
add [fo], filebuffer_size
cmp eax, filebuffer_size
je .packet
add eax, 4
mov [packetsize], eax
; ijhidfhfdsndsfqk
.packet:
movzx esi, [last_ack]
and esi, 0x000000001f ; last five bits BUFFER SIZE MUST BE 16 kb for this to work !!!
shl esi, 9 ; = * 512
add esi, [fb]
mov edi, buffer
mov ax, opcode_data
stosw
mov ax, [last_ack]
stosw
mov ecx, 512/4
rep movsd
mcall send, [socketnum], buffer, 4+512, 0 ; send data
.send_packet:
mcall send, [socketnum], buffer, [packetsize], 0 ; send data
.loop:
mcall 23, TIMEOUT
dec eax
jz .red
dec eax
dec eax
jz .btn
jz .key
mcall recv, [socketnum], [packetbuff], buffer_len ; receive ack
cmp eax, -1
je .kill_xfer
mcall recv, [socketnum], buffer, buffer_len, 0 ; receive ack
mov esi, [packetbuff]
cmp word[esi], opcode_error
je .decode_error
cmp word[esi], opcode_ack
jne .send_packet
cmp word[buffer], opcode_ack
jne .exit
mov ax, [last_ack]
xchg al, ah
cmp word[esi+2], ax
jne .send_packet
cmp word[buffer+2], ax
jne .packet
inc [last_ack]
test [last_ack],0x001f
jz .read_chunk
jmp .packet
cmp [packetsize], 512+4
jne .xfer_ok ; transfer is done
jmp .read_chunk
.red:
call draw_window
jmp .loop
.btn:
mcall 17
.key:
mcall 2
cmp ah, 2
jz exit
.kill_xfer:
mov [status], str_fail
; close socket ?
.xfer_done:
jmp .loop
.exit:
invoke file_close, [fh]
mcall close, [socketnum]
jmp stop_transfer
jmp still
.xfer_ok:
mov [status], str_success
jmp .xfer_done
.decode_error:
movzx esi, word[esi + 2]
cmp esi, 7
cmovg esi, [zero]
mov esi, dword [4*esi + error_crosslist]
mov [status], esi
jmp .send_packet
@ -500,16 +450,16 @@ done dd 0
sockaddr:
dw AF_INET4
dw 69 shl 8
dw 69
IP db 192,168,1,115
sockaddr_len = $ - sockaddr
align 16
@IMPORT:
library box_lib , 'box_lib.obj',\
io_lib , 'libio.obj',\
network , 'network.obj'
library box_lib , 'box_lib.obj'
library io_lib , 'libio.obj'
library network , 'network.obj'
import box_lib ,\
edit_box_draw ,'edit_box' ,\
@ -544,10 +494,9 @@ import network ,\
freeaddrinfo , 'freeaddrinfo'
edit1 edit_box 300,80,5 ,0xffffff,0x6f9480,0,0,0,99 ,SRV,ed_focus, 13,13
edit2 edit_box 300,80,25,0xffffff,0x6a9480,0,0,0,99 ,remote_addr,ed_figure_only, 5,5
edit3 edit_box 300,80,45,0xffffff,0x6a9480,0,0,0,99 ,local_addr,ed_figure_only, 13,13
edit1 edit_box 300,80,5 ,0xffffff,0x6f9480,0,0,0,99 ,SRV,ed_focus, 11,11
edit2 edit_box 300,80,25,0xffffff,0x6a9480,0,0,0,99 ,remote_addr,ed_figure_only, 10,10
edit3 edit_box 300,80,45,0xffffff,0x6a9480,0,0,0,99 ,local_addr,ed_figure_only, 27,27
edit4 edit_box 40,340,68,0xffffff,0x6a9480,0,0,0,5 ,BLK,ed_figure_only, 3,3
op1 option_box option_group1,80,68,6,12,0xffffff,0,0,netascii,octet-netascii
@ -558,7 +507,6 @@ op4 option_box option_group2,210,85,6,12,0xFFFFFF,0,0,put,BLK-put
option_group1 dd op1
option_group2 dd op3
Option_boxs1 dd op1,op2,0
Option_boxs2 dd op3,op4,0
@ -572,11 +520,6 @@ str_blocksize db 'Blocksize:',0
str_kb_s db 'kb/s',0
str_complete db '% complete',0
str_transfer db 'Transfer',0
str_waiting db 'Welcome!',0
str_transfering db 'Transfering...',0
str_success db 'Tranfser completed sucessfully',0
str_fail db 'Transfer failed!',0
str_error:
._0 db 'Not defined, see error message (if any).',0
@ -589,18 +532,6 @@ str_error:
._7 db 'No such user.',0
error_crosslist:
dd str_error._0
dd str_error._1
dd str_error._2
dd str_error._3
dd str_error._4
dd str_error._5
dd str_error._6
dd str_error._7
netascii db 'NetASCII'
octet db 'Octet'
get db 'GET'
@ -611,25 +542,19 @@ BLK db "512",0,0,0
last_ack dw ?
fh dd ? ; file handle
last_time dd ?
packetbuff dd ?
packetsize dd ?
status dd str_waiting
zero dd 0
fo dd ? ; file offset
fb dd ? ; file buffer
SRV db "192.168.1.115",0
times (SRV + 256 - $) db 0
rb (SRV + 256 - $)
remote_addr db "3.png",0
times (remote_addr + 256 - $) db 0
remote_addr db "IMG00",0
rb (remote_addr + 256 - $)
local_addr db "/sys/test.png",0
times (local_addr + 256 - $) db 0
local_addr db "/hd0/1/KolibriOS/kernel.mnt",0
rb (local_addr + 256 - $)
I_END:
buffer:
rb buffer_len

View File

@ -131,29 +131,8 @@ START: ; start of execution
mcall 40, 1 shl 7 ; network event
; eth.set_network_drv 0x00000383
DEBUGF 1,">Zero-config service:\n"
; eth.status eax ; Read the Stack status
; test eax,eax ; if eax is zero, no driver was found
; jnz @f
; DEBUGF 1,"No Card found!\n"
; jmp close
; @@:
; DEBUGF 1,"Detected card: %x\n",eax
; @@:
; eth.check_cable eax
; test al,al
; jnz @f
; DEBUGF 1,"Cable disconnected!\n"
; mcall 5, 500 ; loop until cable is connected (check every 5 sec)
; jmp @r
; @@:
; eth.read_mac MAC
mcall 75, 1337 shl 16 + 4
cmp eax, -1
@ -254,6 +233,7 @@ buildRequest: ; Creates a DHCP request packet.
test eax,eax
jz apipa
;;; todo: skip this bullcrap
mov edi, eax
mov ecx, BUFFER
@ -261,12 +241,14 @@ buildRequest: ; Creates a DHCP request packet.
cld
rep stosb
;; todo: put this in a buffer instead of writing bytes and words!
mov edx,[dhcpMsg]
mov [edx], byte 0x01 ; Boot request
mov [edx+1], byte 0x01 ; Ethernet
mov [edx+2], byte 0x06 ; Ethernet h/w len
mov [edx+4], dword 0x11223344 ; xid
mov [edx+4], dword 0x11223344 ; xid ;;;;;;;
mov eax,[currTime]
mov [edx+8], eax ; secs, our uptime
mov [edx+10], byte 0x80 ; broadcast flag set
@ -274,7 +256,7 @@ buildRequest: ; Creates a DHCP request packet.
mov [edx+28],dword eax
mov ax, word [MAC+4] ; last 2 bytes of MAC
mov [edx+32],word ax
mov [edx+236], dword 0x63538263 ; magic number
mov [edx+236], dword 0x63538263 ; magic cookie
mov [edx+240], word 0x0135 ; option DHCP msg type
mov al, [dhcpMsgType]
mov [edx+240+2], al
@ -313,7 +295,6 @@ send_request:
mcall 23, TIMEOUT*10 ; wait for data
read_data: ; we have data - this will be the response
mcall 74, 7, [socketNum], [dhcpMsg], BUFFER ; read data from socket
DEBUGF 1,"->%d bytes received\n", eax
@ -464,7 +445,7 @@ pr001:
pr_exit:
; DEBUGF 1,"Sending ARP announce\n"
; eth.ARP_ANNOUNCE [dhcpClientIP] ; send an ARP announce packet
;;;
jmp close
@ -572,7 +553,7 @@ str_type db 'type',0
sockaddr1:
dw AF_INET4
dw 68 shl 8 ; local port
dw 68 ; local port
dd 0 ; local IP
rb 10
@ -581,7 +562,7 @@ sockaddr1:
sockaddr2:
dw AF_INET4
dw 67 shl 8 ; destination port
dw 67 ; destination port
dd -1 ; destination IP
rb 10

View File

@ -78,10 +78,11 @@ iglobal
szStrchr db 'strchr',0
szStrrchr db 'strrchr',0
szNetRegDev db 'NetRegDev',0
szNetUnRegDev db 'NetUnRegDev',0
szNetPtrToNum db 'NetPtrToNum',0
szEthReceiver db 'EthReceiver',0
szEthRegDev db 'EthRegDev',0
szEthUnRegDev db 'EthUnRegDev',0
szEthStruc2Dev db 'EthStruc2Dev',0
szIPv4Handler db 'IPv4Handler',0
align 16
@ -151,10 +152,11 @@ kernel_export:
dd szStrchr , strchr
dd szStrrchr , strrchr
dd szNetRegDev , NET_add_device
dd szNetUnRegDev , NET_remove_device
dd szNetPtrToNum , NET_ptr_to_num
dd szEthReceiver , ETH_receiver
dd szEthRegDev , ETH_add_device
dd szEthUnRegDev , ETH_remove_device
dd szEthStruc2Dev , ETH_struc2dev
dd szIPv4Handler , IPv4_handler
exp_lfb:
dd szLFBAddress , 0

View File

@ -812,6 +812,10 @@ term9:
and [application_table_status],0
;mov esi,process_terminated
;call sys_msg_board_str
mov eax, [.slot]
call SOCKET_process_end
add esp, 4
ret
restore .slot

View File

@ -545,7 +545,8 @@ proc service_proc stdcall, ioctl:dword
.register:
call EthRegDev
mov [device.type], NET_TYPE_ETH
call NetRegDev
cmp eax, -1
je .destroy
@ -566,7 +567,7 @@ proc service_proc stdcall, ioctl:dword
.find_devicenum:
DEBUGF 1,"Trying to find device number of already registered device\n"
call EthStruc2Dev ; This kernel procedure converts a pointer to device struct in ebx
call NetPtrToNum ; This kernel procedure converts a pointer to device struct in ebx
; into a device number in edi
mov eax, edi ; Application wants it in eax instead
DEBUGF 1,"Kernel says: %u\n", eax

View File

@ -309,7 +309,9 @@ proc service_proc stdcall, ioctl:dword
mov [DEVICE_LIST+4*eax], ebx
inc [DEVICES]
call EthRegDev ; Register the device to kernel (ebx points to device struct)
mov [device.type], NET_TYPE_ETH
call NetRegDev
cmp eax, -1
jz .err
ret 4
@ -320,7 +322,7 @@ proc service_proc stdcall, ioctl:dword
.find_devicenum:
DEBUGF 1,"Trying to find device number of already registered device\n"
mov ebx, eax
call EthStruc2Dev ; This kernel procedure converts a pointer to device struct in ebx
call NetPtrToNum ; This kernel procedure converts a pointer to device struct in ebx
; into a device number in edi
mov eax, edi ; Application wants it in eax instead
DEBUGF 1,"Kernel says: %u\n", eax
@ -372,7 +374,7 @@ find_device_num:
DEBUGF 1,"Trying to find device number of already registered device\n"
mov ebx, eax
call EthStruc2Dev ; This kernel procedure converts a pointer to device struct in ebx
call NetPtrToNum ; This kernel procedure converts a pointer to device struct in ebx
; into a device number in edi
mov eax, edi ; Application wants it in eax instead
DEBUGF 1,"Kernel says: %u\n", eax

View File

@ -1,6 +1,6 @@
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; ;;
;; Copyright (C) KolibriOS team 2004-2008. All rights reserved. ;;
;; Copyright (C) KolibriOS team 2004-2010. All rights reserved. ;;
;; Distributed under terms of the GNU General Public License ;;
;; ;;
;; Realtek 8139 driver for KolibriOS ;;
@ -368,7 +368,9 @@ proc service_proc stdcall, ioctl:dword
inc [RTL8139_DEV] ;
call EthRegDev
mov [device.type], NET_TYPE_ETH
call NetRegDev
cmp eax, -1
je .destroy
@ -378,8 +380,7 @@ proc service_proc stdcall, ioctl:dword
.find_devicenum:
DEBUGF 2,"Trying to find device number of already registered device\n"
mov ebx, eax
call EthStruc2Dev ; This kernel procedure converts a pointer to device struct in ebx
call NetPtrToNum ; This kernel procedure converts a pointer to device struct in ebx
; into a device number in edi
mov eax, edi ; Application wants it in eax instead
DEBUGF 2,"Kernel says: %u\n", eax
@ -445,19 +446,22 @@ probe:
shr ah , 2
shr ax , 6
and al , 01111111b
mov ecx, HW_VER_ARRAY_SIZE-1
.chip_ver_loop:
cmp al , [hw_ver_array + ecx]
je .chip_ver_found
dec ecx
jns .chip_ver_loop
xor cl , cl ; default RTL8139
.unknown:
mov ecx, 8
.chip_ver_found:
cmp ecx, 8
jg .unknown
mov [device.hw_ver_id], cl
shl ecx, 2
add ecx, crosslist
mov ecx, [ecx]
mov ecx, [crosslist + ecx*4]
mov [device.name], ecx
DEBUGF 2,"Chip version: %s\n", ecx
@ -1223,6 +1227,7 @@ device_5 db 'Realtek 8100',0
device_6 db 'Realtek 8139D',0
device_7 db 'Realtek 8139CP',0
device_8 db 'Realtek 8101',0
device_unknown db 'Unknown RTL8139 clone', 0
crosslist dd device_1
dd device_2
@ -1232,6 +1237,7 @@ crosslist dd device_1
dd device_6
dd device_7
dd device_8
dd device_unknown
hw_ver_array db VER_RTL8139 ; This array is used by the probe routine to find out wich version of the RTL8139 we are working with
db VER_RTL8139A
@ -1241,6 +1247,7 @@ hw_ver_array db VER_RTL8139 ; This array is used by the probe routine to find
db VER_RTL8139D
db VER_RTL8139CP
db VER_RTL8101
db 0
HW_VER_ARRAY_SIZE = $-hw_ver_array

View File

@ -449,7 +449,10 @@ proc service_proc stdcall, ioctl:dword
test eax, eax
jnz .err2 ; If an error occured, exit
call EthRegDev
mov [device.type], NET_TYPE_ETH
call NetRegDev
cmp eax, -1
je .destroy
@ -460,7 +463,7 @@ proc service_proc stdcall, ioctl:dword
.find_devicenum:
DEBUGF 2,"Trying to find device number of already registered device\n"
mov ebx, eax
call EthStruc2Dev ; This kernel procedure converts a pointer to device struct in ebx
call NetPtrToNum ; This kernel procedure converts a pointer to device struct in ebx
; into a device number in edi
mov eax, edi ; Application wants it in eax instead
DEBUGF 2,"Kernel says: %u\n", eax

View File

@ -88,7 +88,7 @@ kernel_export \
\
LFBAddress,\
\
EthReceiver,\
EthRegDev,\
EthUnRegDev,\
EthStruc2Dev
NetRegDev,\
NetUnRegDev,\
NetPtrToNum,\
EthReceiver

View File

@ -23,6 +23,12 @@
PAGESIZE equ 4096
; network driver types
NET_TYPE_ETH equ 1
NET_TYPE_SLIP equ 2
LAST_IO = 0
@ -135,10 +141,12 @@ macro make_bus_master bus, dev {
movzx edx, dev
stdcall PciRead32, ecx ,edx, PCI_REG_COMMAND
or al, PCI_BIT_MASTER or PCI_BIT_PIO
and al, not PCI_BIT_MMIO
or al, PCI_BIT_MASTER ;or PCI_BIT_PIO
; and al, not PCI_BIT_MMIO
stdcall PciWrite32, ecx, edx, PCI_REG_COMMAND, eax
;; TODO: try to switch to PIO, and check if PIO works or not..
}
struc IOCTL {
@ -178,9 +186,13 @@ macro virt_to_dma { ; input is eax
}
macro NET_DEVICE {
.type dd ?
}
;struc ETH_DEVICE {
macro ETH_DEVICE {
NET_DEVICE
; pointers to procedures
.unload dd ?
.reset dd ?
@ -202,6 +214,7 @@ macro ETH_DEVICE {
macro SLIP_DEVICE {
NET_DEVICE
; pointers to procedures
.unload dd ?
.reset dd ?

View File

@ -553,7 +553,9 @@ proc service_proc stdcall, ioctl:dword
test eax, eax
jnz .destroy ; If an error occured, exit
call EthRegDev
mov [device.type], NET_TYPE_ETH
call NetRegDev
cmp eax, -1
je .destroy
@ -564,7 +566,7 @@ proc service_proc stdcall, ioctl:dword
.find_devicenum:
DEBUGF 1,"Trying to find device number of already registered device\n"
mov ebx, eax
call EthStruc2Dev ; This kernel procedure converts a pointer to device struct in ebx
call NetPtrToNum ; This kernel procedure converts a pointer to device struct in ebx
; into a device number in edi
mov eax, edi ; Application wants it in eax instead
DEBUGF 1,"Kernel says: %u\n", eax

View File

@ -36,23 +36,11 @@ format MS COFF
include 'proc32.inc'
include 'imports.inc'
include 'fdo.inc'
include 'netdrv.inc'
public START
public version
struc IOCTL {
.handle dd ?
.io_code dd ?
.input dd ?
.inp_size dd ?
.output dd ?
.out_size dd ?
}
virtual at 0
IOCTL IOCTL
end virtual
NUM_RX_DESC equ 4 ;* Number of RX descriptors *
NUM_TX_DESC equ 1 ;* Number of TX descriptors *
RX_BUFF_SZ equ 1520 ;* Buffer size for each Rx buffer *
@ -61,23 +49,11 @@ MAX_ETH_FRAME_SIZE equ 1516
TOTAL_BUFFERS_SIZE equ NUM_RX_DESC*RX_BUFF_SZ + NUM_TX_DESC*TX_BUFF_SZ
struc ETH_DEVICE {
; pointers to procedures
.unload dd ?
.reset dd ?
.transmit dd ?
.set_MAC dd ?
.get_MAC dd ?
.set_mode dd ?
.get_mode dd ?
; status & variables
.bytes_tx dq ?
.bytes_rx dq ?
.packets_tx dd ?
.packets_rx dd ?
.mode dd ? ; This dword contains cable status (10mbit/100mbit, full/half duplex, auto negotiation or not,..)
.name dd ?
.mac dp ?
virtual at 0
device:
ETH_DEVICE
; device specific
.io_addr dd ?
.pci_bus db ?
@ -91,7 +67,7 @@ align 4
.txd: times (3 * NUM_TX_DESC) dd 0
.rxd: times (3 * NUM_RX_DESC) dd 0
.size:
}
end virtual
; First page is designated to ETH_DEVICE, buffers start from second
ALLOCATION_SIZE = ((device.size+0FFFh) and not 0FFFh) + TOTAL_BUFFERS_SIZE
@ -102,9 +78,6 @@ ALLOCATION_SIZE = (ALLOCATION_SIZE + 7FFFh) and not 7FFFh
MAX_DEVICES = 16 ; maximum number of devices which this driver can handle
virtual at 0
device ETH_DEVICE
end virtual
PCI_HEADER_TYPE equ 0x0e ;8 bit
PCI_BASE_ADDRESS_0 equ 0x10 ;32 bit
@ -238,7 +211,9 @@ service_proc:
jnz .destroy
; 4n. If device was successfully initialized, register it for the kernel.
call EthRegDev
mov [device.type], NET_TYPE_ETH
call NetRegDev
cmp eax, -1
je .destroy
@ -248,7 +223,7 @@ service_proc:
.find_devicenum:
mov ebx, eax
call EthStruc2Dev ; This kernel procedure converts a pointer to device struct in ebx
call NetPtrToNum ; This kernel procedure converts a pointer to device struct in ebx
; into a device number in edi
mov eax, edi ; Application wants it in eax instead
ret 4

View File

@ -1,6 +1,6 @@
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;
;; Copyright (C) KolibriOS team 2004-2009. All rights reserved.
;; Copyright (C) KolibriOS team 2004-2010. All rights reserved.
;; PROGRAMMING:
;; Ivan Poddubny
;; Marat Zakiyanov (Mario79)

View File

@ -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 ;;
;; ;;
;; ARP.INC ;;
@ -12,7 +12,7 @@
;; Written by hidnplayr@kolibrios.org ;;
;; ;;
;; GNU GENERAL PUBLIC LICENSE ;;
;; Version 2, June 1991 ;;
;; Version 2, June- 1991 ;;
;; ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
@ -242,15 +242,14 @@ ARP_create_request:
mov eax, [IP_LIST+4*edi] ; senderIP
push eax
mov edi, [ETH_DRV_LIST + 4*edi]
mov edi, [NET_DRV_LIST + 4*edi]
lea eax, [edi + ETH_DEVICE.mac]
mov ebx, ETH_BROADCAST
mov ecx, 60 ; minimum packet size
mov edx, edi ;;;
mov di , ETHER_ARP
call ETH_create_packet
cmp edi, -1
je .exit
jz .exit
mov ecx, eax
@ -275,7 +274,7 @@ ARP_create_request:
DEBUGF 1,"ARP Packet for device %x created successfully\n", ebx
push edx ecx
jmp ETH_sender
jmp NET_send
.exit:
add esp, 8
@ -523,7 +522,7 @@ ARP_handler:
cmp word [edx + ARP_Packet.Opcode], ARP_REQ_OPCODE ; Is this a request packet?
jne .exit
call ETH_struc2dev
call NET_ptr_to_num
DEBUGF 1,"ARP Request packet through device: %u\n", edi
inc [ARP_PACKETS_RX+4*edi]
cmp edi, -1
@ -549,7 +548,7 @@ ARP_handler:
movsd ; Move sender IP to Dest IP
pop esi
mov esi, [ETH_DRV_LIST + 4*esi]
mov esi, [NET_DRV_LIST + 4*esi]
lea esi, [esi + ETH_DEVICE.mac]
lea edi, [edx + ARP_Packet.SenderMAC]
movsd ; Copy MAC address from in MAC_LIST
@ -573,7 +572,7 @@ ARP_handler:
DEBUGF 1,"ARP_Handler - Sending reply \n"
jmp ETH_sender ; And send it!
jmp NET_send ; And send it!
.exit:
call kernel_free

View File

@ -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 ;;
;; ;;
;; IPv4.INC ;;
@ -18,16 +18,13 @@
$Revision$
; IP underlying protocols numbers
ETHER_IPv4 equ 0x0008 ; Reversed from 0800 for intel
MAX_FRAGMENTS equ 16
MAX_FRAGMENTS equ 64
MAX_IP equ MAX_NET_DEVICES
IP_MAX_INTERFACES equ MAX_IP
struct IPv4_Packet
.VersionAndIHL db ? ; Version[0-3 bits] and IHL(header length)[4-7 bits]
.TypeOfService db ?
.TypeOfService db ? ; precedence [7-5] minimize delay [4], maximize throughput [3], maximize riliability [2] minimize momentary cost [1] and zero [0]
.TotalLength dw ?
.Identification dw ?
.FlagsAndFragmentOffset dw ? ; Flags[0-2] and FragmentOffset[3-15]
@ -58,13 +55,15 @@ ends
align 4
uglobal
BROADCAST dd ?
IP_LIST rd MAX_IP
SUBNET_LIST rd MAX_IP
DNS_LIST rd MAX_IP
GATEWAY_LIST rd MAX_IP
IP_PACKETS_TX rd MAX_IP
IP_PACKETS_RX rd MAX_IP
FRAGMENT_LIST rb MAX_FRAGMENTS*FRAGMENT_slot.size
endg
@ -83,11 +82,11 @@ align 4
IPv4_init:
or eax, -1
mov edi, BROADCAST
mov ecx, 4*MAX_IP+1
mov edi, IP_LIST
mov ecx, 4*MAX_IP
rep stosd
xor eax, eax
inc eax
mov edi, FRAGMENT_LIST
mov ecx, FRAGMENT_slot.size*MAX_FRAGMENTS/4 + 2*MAX_IP
rep stosd
@ -114,10 +113,12 @@ IPv4_init:
;-----------------------------------------------------------------
align 4
IPv4_handler: ; TODO: implement handler for IP options
; TODO2: add code for IPv4 sockets (raw sockets)
DEBUGF 1,"IP_Handler - start\n"
; TODO2: add code for raw sockets
DEBUGF 1,"IPv4_Handler, packet from: %u.%u.%u.%u ",\
[edx + IPv4_Packet.SourceAddress]:1,[edx + IPv4_Packet.SourceAddress + 1]:1,[edx + IPv4_Packet.SourceAddress + 2]:1,[edx + IPv4_Packet.SourceAddress + 3]:1
DEBUGF 1,"to: %u.%u.%u.%u\n",\
[edx + IPv4_Packet.DestinationAddress]:1,[edx + IPv4_Packet.DestinationAddress + 1]:1,[edx + IPv4_Packet.DestinationAddress + 2]:1,[edx + IPv4_Packet.DestinationAddress + 3]:1
;-------------------------------------------
; Check if the packet still has time to live
@ -133,61 +134,66 @@ IPv4_handler: ; TODO: implement handler for IP options
cmp al , 0x05 ; IHL!= 5*4(20 bytes)
jnz .has_options
;-------------------------------
; Now, re-calcualte the checksum
; Now, re-calculate the checksum
; Re-calculate checksum
push edx ebx
mov esi, edx
call IPv4_checksum
pop ebx edx
; now see if it was correct
cmp [edx + IPv4_Packet.HeaderChecksum], 0
jne .dump ; if checksum isn't valid then dump packet
DEBUGF 1,"IPv4 Checksum is correct\n"
;-------------------------------------------------------
; Time to find out what interface this packet belongs to
;-----------------------------------
; Check if destination IP is correct
; Therefore we will scan the current list of IP's
call NET_ptr_to_num
shl edi, 2
mov eax, [edx + IPv4_Packet.DestinationAddress]
mov edi, BROADCAST
mov ecx, MAX_IP+1
; check if it matches local ip
.find_ip_loop:
cmp eax, dword [edi]
jz .ip_ok
add edi, 4
dec ecx
jnz .find_ip_loop
mov eax, dword[IP_LIST+edi]
cmp [edx + IPv4_Packet.DestinationAddress], eax
je .ip_ok
; it was not on the list, perhaps it's a loopback ?
; check for broadcast
mov eax, dword[SUBNET_LIST+edi]
not eax
test eax, 127 shl 24 ; 127.x.x.x
jz .ip_ok
or eax, dword[IP_LIST+edi]
cmp [edx + IPv4_Packet.DestinationAddress], eax
je .ip_ok
; TODO: we need to check for broadcasts (other then 255.255.255.255)
; or a special broadcast
cmp [edx + IPv4_Packet.DestinationAddress], -1
je .ip_ok
; ; maybe it's a multicast then
;
; mov eax, [edx + IPv4_Packet.DestinationAddress]
; and eax, 0xff000000
; cmp eax, 224 shl 24
; je .ip_ok
; or a loopback address
cmp eax, 127 shl 24
je .ip_ok
; or it's not meant for us..
DEBUGF 2,"Destination address does not match!\n"
jmp .dump
;---------------------------------------------------
; Now we can update stats and find the device number
;------------------------
; Now we can update stats
.ip_ok:
call ETH_struc2dev ; TODO: make this work on other protocols too!
inc [IP_PACKETS_RX+4*edi]
DEBUGF 1,"Packet comes from %u.%u.%u.%u\n",\
[edx + IPv4_Packet.SourceAddress]:1,[edx + IPv4_Packet.SourceAddress + 1]:1,[edx + IPv4_Packet.SourceAddress + 2]:1,[edx + IPv4_Packet.SourceAddress + 3]:1
inc [IP_PACKETS_RX+edi]
;----------------------------------
; Check if the packet is fragmented
@ -198,14 +204,12 @@ IPv4_handler: ; TODO: implement handler for IP options
test [edx + IPv4_Packet.FlagsAndFragmentOffset], 0xff1f ; If flag is not set, but there is a fragment offset, the packet is last in series of fragmented packets
jnz .is_last_fragment
;-------------------------------------------------------------------
; No, it's just a regular IP packet, pass it to the higher protocols
.handle_it: ; We reach here if packet hasnt been fragmented, or when it already has been re-constructed
movzx eax, byte [edx + IPv4_Packet.VersionAndIHL] ; Calculate Header length by using IHL field
and eax, 0x0000000F ;
and eax, 0x0000000f ;
shl eax, 2 ;
movzx ecx, word [edx + IPv4_Packet.TotalLength] ; Calculate length of encapsulated Packet
xchg cl , ch ;
@ -220,13 +224,13 @@ IPv4_handler: ; TODO: implement handler for IP options
pop edx ; Offset to data (tcp/udp/icmp/.. Packet)
cmp al , IP_PROTO_TCP
je TCP_handler
je TCP_input
cmp al , IP_PROTO_UDP
je UDP_handler
je UDP_input
cmp al , IP_PROTO_ICMP
je ICMP_handler
je ICMP_input
DEBUGF 2,"unknown Internet protocol: %u\n", al
@ -351,7 +355,7 @@ IPv4_handler: ; TODO: implement handler for IP options
cmp esi, -1
jne .count_bytes
mov esi, [esp+4] ;;;
mov esi, [esp+4]
mov [edi + FRAGMENT_entry.NextPtr], esi ; Add this packet to the chain, this simplifies the following code
mov [esi + FRAGMENT_entry.NextPtr], -1
mov [esi + FRAGMENT_entry.PrevPtr], edi
@ -463,13 +467,15 @@ IPv4_handler: ; TODO: implement handler for IP options
;
; find fragment slot
;
; IN: pointer to fragmented packet in edx ; TODO: the RFC says we should check protocol too
; IN: pointer to fragmented packet in edx
; OUT: pointer to slot in edi, -1 on error
;
;-----------------------------------------------------------------
align 4
IPv4_find_fragment_slot:
;;; TODO: the RFC says we should check protocol number too
push eax ebx ecx edx
mov ax , word [edx + IPv4_Packet.Identification]
mov ecx, MAX_FRAGMENTS
@ -514,7 +520,7 @@ IPv4_decrease_fragment_ttls:
dec [esi + FRAGMENT_slot.ttl]
jnz .try_next
DEBUGF 1,"Fragment slot timed-out!\n"
; TODO: clear all entry's of timed-out slot
;;; TODO: clear all entry's of timed-out slot
.try_next:
add esi, 4
loop .loop
@ -524,33 +530,58 @@ IPv4_decrease_fragment_ttls:
;-----------------------------------------------------------------
;------------------------------------------------------------------
;
;
; IN: dword [esp] = pointer to packet to be fragmented
; dword [esp+4] = buffer size
; edx = pointer to IPv4 header in that packet
; ecx = data length
; ebx = device structure
;
; OUT: /
;
;------------------------------------------------------------------
align 4
IPv4_fragment:
;;; TODO: write code here
call kernel_free
add esp, 4
ret
;------------------------------------------------------------------
;
; Create_IPv4_Packet
;
; IN: eax = dest ip
; ebx = source ip
; ecx = data length
; dx = fragment id
; dx = fragment id ;;;;
; di = protocol
;
; OUT: eax = pointer to buffer start
; ebx = pointer to device struct (needed for sending procedure)
; ecx = unchanged (packet size of embedded data)
; edx = size of complete buffer
; esi = pointer to sending procedure
; edi = pointer to start of data (-1 on error)
; edi = pointer to start of data (0 on error)
;
;----------------------------------------------------------------- ;;; TODO: create fragmented packets
;------------------------------------------------------------------
align 4
IPv4_create_packet:
DEBUGF 1,"Create IPv4 Packet (size=%u)\n", ecx
cmp ecx, 1480
cmp ecx, 65500 ; Max IPv4 packet size
jg .exit_
test ebx, ebx ; if dest ip = 0
test ebx, ebx ; if source ip = 0
jnz .ip_ok ; and local ip is valid
; use local ip instead
cmp [IP_LIST],0xffffffff ;
@ -582,16 +613,17 @@ IPv4_create_packet:
.send:
call IPv4_dest_to_dev
inc [IP_PACKETS_TX+4*edi]
mov edx, [ETH_DRV_LIST + 4*edi]
mov edx, [NET_DRV_LIST + 4*edi]
lea eax, [edx + ETH_DEVICE.mac]
mov ebx, esp
mov ecx, [esp+18] ;; 18 or 22 ??
add ecx, IPv4_Packet.DataOrOptional
mov di , ETHER_IPv4
call ETH_create_packet ; TODO: figure out a way to make this work with other protocols too
;;; TODO: detect if packet is too large for ethernet, if so, call IPv4_fragment
call ETH_create_packet ;;; TODO: figure out a way to make this work with other protocols too
add esp, 6
cmp edi, -1
je .exit
test edi, edi
jz .exit
mov [edi + IPv4_Packet.VersionAndIHL], 0x45 ; IPv4, normal length (no Optional header)
mov [edi + IPv4_Packet.TypeOfService], 0
@ -622,12 +654,12 @@ IPv4_create_packet:
.not_found:
DEBUGF 1,"Create IPv4 Packet - ARP entry not found!\n"
; TODO: QUEUE the packet to resend later!
;;;;;;
.exit:
add esp, 16
.exit_:
DEBUGF 1,"Create IPv4 Packet - failed\n"
or edi, -1
and edi, 0
ret

View File

@ -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 ;;
;; ;;
;; ETHERNET.INC ;;
@ -16,17 +16,18 @@
$Revision$
MAX_ETH_DEVICES equ MAX_NET_DEVICES
ETH_QUEUE_SIZE equ 16
struct ETH_FRAME
.DstMAC dp ? ; destination MAC-address [6 bytes]
.SrcMAC dp ? ; source MAC-address [6 bytes]
.Type dw ? ; type of the upper-layer protocol [2 bytes]
.Data: ; data [46-1500 bytes]
.DstMAC dp ? ; destination MAC-address
.SrcMAC dp ? ; source MAC-address
.Type dw ? ; type of the upper-layer protocol
.Data: ; data (46-1500 bytes for a normal packet)
ends
struct ETH_DEVICE
virtual at NET_DEVICE.end
ETH_DEVICE:
.unload dd ?
.reset dd ?
.transmit dd ?
@ -39,18 +40,11 @@ struct ETH_DEVICE
.bytes_rx dq ?
.packets_tx dd ?
.packets_rx dd ?
.mode dd ? ; This dword contains cable status (10mbit/100mbit, full/half duplex, auto negotiation or not,..)
.mode dd ?
.name dd ?
.mac dp ?
ends ; the rest of the device struct depends on the type of device
struct eth_queue_entry
.owner dd ?
.data_ptr dd ?
.data_size dd ?
.size:
ends
end virtual
align 4
iglobal
@ -60,13 +54,7 @@ endg
align 4
uglobal
ETH_RUNNING dd ?
ETH_DRV_LIST rd MAX_ETH_DEVICES
ETH_IN_QUEUE rd 3*ETH_QUEUE_SIZE+3
if QUEUE_BEFORE_SENDING
ETH_OUT_QUEUE rd 3*ETH_QUEUE_SIZE+3
end if
endg
@ -83,126 +71,11 @@ endg
align 4
ETH_init:
xor eax, eax
mov edi, ETH_RUNNING
mov ecx, (1+MAX_ETH_DEVICES)
rep stosd
init_queue ETH_IN_QUEUE
if QUEUE_BEFORE_SENDING
init_queue ETH_OUT_QUEUE
end if
mov [ETH_RUNNING], 0
ret
;-----------------------------------------------------------------
;
; ETH_Add_Device:
;
; This function is called by ethernet drivers,
; to register each running ethernet device to the kernel
;
; IN: Pointer to device structure in ebx
; OUT: Device num in eax, -1 on error
;
;-----------------------------------------------------------------
align 4
ETH_add_device:
DEBUGF 1,"ETH_Add_Device: %x ", ebx
mov eax, [ETH_RUNNING]
cmp eax, MAX_ETH_DEVICES
jge .error
test eax, eax
jnz .notfirst
mov dword [ETH_IN_QUEUE], eax
if QUEUE_BEFORE_SENDING
mov dword [ETH_OUT_QUEUE], eax
end if
.notfirst:
mov eax, ebx
mov ecx, MAX_ETH_DEVICES ; We need to check whole list because a device may be removed without re-organizing list
mov edi, ETH_DRV_LIST
repne scasd ; See if device is already in the list
jz .error
xor eax, eax
mov ecx, MAX_ETH_DEVICES
mov edi, ETH_DRV_LIST
repne scasd ; Find empty spot in the list
jnz .error
sub edi, 4
mov [edi], ebx ; add device to list
sub edi, ETH_DRV_LIST ; edi = 4*device num Calculate device number in eax
mov eax, edi ; edx = 4*device num
shr eax, 2
inc [ETH_RUNNING] ; Indicate that one more ethernet device is up and running
DEBUGF 1,"- succes: %u\n",eax
ret
.error:
or eax, -1
DEBUGF 2,"Adding ETH device failed\n"
ret
;-----------------------------------------------------------------
;
; ETH_Remove_Device:
;
; This function is called by ethernet drivers,
; to unregister ethernet devices from the kernel
;
; IN: Pointer to device structure in ebx
; OUT: eax: -1 on error
;
;-----------------------------------------------------------------
align 4
ETH_remove_device:
cmp [ETH_RUNNING], 0
je .error
mov eax, ebx
mov ecx, MAX_ETH_DEVICES
mov edi, ETH_DRV_LIST
repne scasd
jnz .error
xor eax, eax
mov dword [edi-4], eax
dec [ETH_RUNNING]
jnz .notlast
mov dword [ETH_IN_QUEUE], ETH_QUEUE_SIZE
if QUEUE_BEFORE_SENDING
mov dword [ETH_OUT_QUEUE], ETH_QUEUE_SIZE
end if
.notlast:
ret
.error:
or eax, -1
ret
;-----------------------------------------------------------------
;
; ETH_Receiver:
@ -218,57 +91,8 @@ end if
;-----------------------------------------------------------------
align 4
ETH_receiver:
; DEBUGF 1,"ETH_Receiver: "
; push ebx
; mov esi, esp
; add_to_queue ETH_IN_QUEUE, ETH_QUEUE_SIZE, eth_queue_entry.size, .fail
; DEBUGF 1,"Queued packet successfully\n"
; add esp, 4*3
;
; ret
;
; .fail:
; DEBUGF 1,"ETH_IN_QUEUE is full!\n"
; add esp, 4
; call kernel_free
; add esp, 4
;
; ret
;
;
;
;;-----------------------------------------------------------------
;;
;; ETH_Handler:
;;
;; Handles all queued eth packets (called from kernel's main_loop)
;;
;; IN: /
;; OUT: /
;;
;;-----------------------------------------------------------------
;align 4
;ETH_handler:
;
; get_from_queue ETH_IN_QUEUE, ETH_QUEUE_SIZE, eth_queue_entry.size, .gohome
;
; push ETH_handler
;
; lodsd
; mov ebx, eax
; lodsd
; mov ecx, eax
; lodsd
; xchg eax, ecx
; push ecx
; push eax
;-----------------------------
mov eax, [esp]
mov ecx, [esp+4]
;-----------------------------
DEBUGF 1,"ETH_Handler - size: %u\n", ecx
cmp ecx, 60 ; check packet length
@ -290,136 +114,23 @@ ETH_receiver:
DEBUGF 2,"ETH_Handler - dumping\n"
call kernel_free
add esp, 4
.gohome:
ret ; return to get more from queue / to caller
align 4
ETH_handler:
ret
;-----------------------------------------------------------------
;
; ETH_sender:
;
; This function sends an ethernet packet to the correct driver.
;
; IN: Pointer to buffer in [esp]
; size of buffer in [esp+4]
; pointer to device struct in ebx
; OUT: /
;
;-----------------------------------------------------------------
align 4
ETH_sender:
if QUEUE_BEFORE_SENDING
DEBUGF 1,"ETH_Sender: queuing for device: %x, %u bytes\n", [esp], [esp + 4]
push ebx
mov esi, esp
add_to_queue ETH_OUT_QUEUE, ETH_QUEUE_SIZE, eth_queue_entry.size, .fail
DEBUGF 1,"Queued packet successfully\n"
add esp, 3*4
ret
.fail:
DEBUGF 1,"ETH_OUT_QUEUE is full!\n"
add esp, 4
call kernel_free
add esp, 4
ret
;-----------------------------------------------------------------
;
; ETH_send_queued:
;
; IN: /
; OUT: /
;
;-----------------------------------------------------------------
align 4
ETH_send_queued:
get_from_queue ETH_OUT_QUEUE, ETH_QUEUE_SIZE, eth_queue_entry.size, .gohome
push ETH_send_queued ; this will cause the procedure to check for more packets
; when a single packet is handled
mov ebx, [esi]
pushd [esi + 8]
pushd [esi + 4]
DEBUGF 1,"dequeued packet for device %x\n", ebx
end if
call [ebx+ETH_DEVICE.transmit] ; we will return to get_from_queue macro after transmitting packet
call kernel_free
add esp, 4 ; pop (balance stack)
.gohome:
ret
;-----------------------------------------------------------------
;
; ETH_struc2dev
;
; IN: pointer to device struct in ebx
;
; OUT: edi is -1 on error, device number otherwise
;
;-----------------------------------------------------------------
align 4
ETH_struc2dev:
push ecx
mov ecx, MAX_ETH_DEVICES
mov edi, ETH_DRV_LIST
.loop:
cmp ebx, [edi]
jz .found
add edi, 4
dec ecx
jnz .loop
or edi, -1
pop ecx
ret
.found:
sub edi, ETH_DRV_LIST
shr edi, 2
pop ecx
ret
;-----------------------------------------------------------------
;
; ETH_create_packet
;
; IN: pointer to source mac in eax
; pointer to destination mac in ebx
; packet size in ecx
; device number in edx
; protocol in di
; IN: eax = pointer to source mac
; ebx = pointer to destination mac
; ecx = packet size
; edx = device number
; di = protocol
;
; OUT: edi is -1 on error, pointer to buffer otherwise
; eax points to buffer start
; ebx is pointer to device structure
; ecx is unchanged (packet size of embedded data)
; edx is size of complete buffer
; esi points to procedure wich needs to be called to send packet
; OUT: edi = 0 on error, pointer to buffer otherwise
; eax = buffer start
; ebx = to device structure
; ecx = unchanged (packet size of embedded data)
; edx = size of complete buffer
;
;-----------------------------------------------------------------
align 4
@ -427,7 +138,7 @@ ETH_create_packet:
DEBUGF 1,"Creating Ethernet Packet (size=%u): \n", ecx
cmp ecx, 1500
cmp ecx, 1500 ;;;
jg .exit
push ecx di eax ebx edx
@ -436,13 +147,13 @@ ETH_create_packet:
push ecx
push ecx
call kernel_alloc
test eax, eax
mov edi, eax
test edi, edi
jz .pop_exit
pop ecx
pop edx
mov edi, eax
pop esi
movsd
movsw
@ -455,10 +166,9 @@ ETH_create_packet:
lea eax, [edi - ETH_FRAME.Data] ; Set eax to buffer start
mov edx, ecx ; Set ebx to complete buffer size
pop ecx
mov esi, ETH_sender
xor ebx, ebx ;;;; TODO: Fixme
mov ebx, [ETH_DRV_LIST + ebx]
mov ebx, [NET_DRV_LIST + ebx]
cmp edx, 46 + ETH_FRAME.Data ; If data size is less then 46, add padding bytes
jg .continue
@ -471,12 +181,12 @@ ETH_create_packet:
.pop_exit:
DEBUGF 2,"Out of ram space!!\n"
add esp, 18
or edi,-1
and edi, 0
ret
.exit:
DEBUGF 2,"Packet too large!\n"
or edi, -1
and edi, 0
ret
@ -497,9 +207,20 @@ ETH_create_packet:
align 4
ETH_API:
cmp bh, MAX_NET_DEVICES
jg .error
movzx eax, bh
shl eax, 2
cmp bl, 7
jz .out_queue
cmp bl, 6
jz .in_queue
mov eax, dword [NET_DRV_LIST + eax]
cmp [eax + NET_DEVICE.type], NET_TYPE_ETH
jne .error
test bl, bl
jz .packets_tx ; 0
dec bl
@ -512,39 +233,28 @@ ETH_API:
jz .read_mac ; 4
dec bl
jz .write_mac ; 5
dec bl
jz .in_queue ; 6
dec bl
jz .out_queue ; 7
.error:
mov eax, -1
DEBUGF 2,"Device is not ethernet type\n"
or eax, -1
ret
.packets_tx:
add eax, ETH_DRV_LIST
mov eax, dword [eax]
mov eax, dword [eax + ETH_DEVICE.packets_tx]
ret
.packets_rx:
add eax, ETH_DRV_LIST
mov eax, dword [eax]
mov eax, dword [eax + ETH_DEVICE.packets_rx]
ret
.bytes_tx:
add eax, ETH_DRV_LIST
mov eax, dword [eax]
mov ebx, dword [eax + ETH_DEVICE.bytes_tx + 4]
mov eax, dword [eax + ETH_DEVICE.bytes_tx]
mov [esp+20+4], ebx ; TODO: fix this ugly code
ret
.bytes_rx:
add eax, ETH_DRV_LIST
mov eax, dword [eax]
mov ebx, dword [eax + ETH_DEVICE.bytes_rx + 4]
mov eax, dword [eax + ETH_DEVICE.bytes_rx]
mov [esp+20+4], ebx ; TODO: fix this ugly code
@ -552,11 +262,6 @@ ETH_API:
.read_mac:
add eax, ETH_DRV_LIST
mov eax, [eax]
; push eax
; call dword [eax + ETH_DEVICE.get_MAC]
; pop eax
movzx ebx, word [eax + ETH_DEVICE.mac]
mov eax, dword [eax + ETH_DEVICE.mac + 2]
mov [esp+20+4], ebx ; TODO: fix this ugly code
@ -565,22 +270,24 @@ ETH_API:
.write_mac:
push ecx
push dx
add eax, ETH_DRV_LIST
mov eax, [eax]
mov eax, dword [eax + ETH_DEVICE.set_MAC]
mov eax, [eax + ETH_DEVICE.set_MAC]
call eax
ret
.in_queue:
if ETH_QUEUE
add eax, ETH_IN_QUEUE
mov eax, [eax + queue.size]
else
or eax, -1
end if
ret
.out_queue:
if QUEUE_BEFORE_SENDING
if ETH_QUEUE
add eax, ETH_OUT_QUEUE
mov eax, [eax + queue.size]
else
mov eax, -1
or eax, -1
end if
ret

View File

@ -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 ;;
;; ;;
;; ICMP.INC ;;
@ -130,10 +130,10 @@ ICMP_init:
;-----------------------------------------------------------------
;
; ICMP_Handler:
; ICMP_input:
;
; this procedure will send reply's to ICMP echo's
; and insert packets into sockets when needed ;;; TODO: update this to work with fragmented packets too!
; This procedure will send reply's to ICMP echo's
; and insert packets into sockets when needed
;
; IN: Pointer to buffer in [esp]
; size of buffer in [esp+4]
@ -144,20 +144,22 @@ ICMP_init:
;
;-----------------------------------------------------------------
align 4
ICMP_handler: ;TODO: works only on pure ethernet right now !
ICMP_input:
DEBUGF 1,"ICMP_Handler - buf:%x size:%x dev:%x, size:%x, buf:%x\n", [esp], [esp+4], ebx, ecx, edx
;;; TODO: works only on pure ethernet right now !
DEBUGF 1,"ICMP_Handler - start\n"
cmp byte [edx + ICMP_Packet.Type], ICMP_ECHO ; Is this an echo request?
jne .check_sockets
;;; TODO: check checksum!
DEBUGF 1,"ICMP_Handler - is echo request, through device:%x\n", ebx
DEBUGF 1,"ICMP_Handler - echo request\n"
mov byte [edx + ICMP_Packet.Type], ICMP_ECHOREPLY ; Change Packet type to reply
mov word [edx + ICMP_Packet.Checksum], 0 ; Set checksum to 0, needed to calculate new checksum
call ETH_struc2dev
call NET_ptr_to_num
cmp edi,-1
je .dump
inc [ICMP_PACKETS_RX+4*edi]
@ -207,8 +209,8 @@ ICMP_handler: ;TODO: works only on pure ethernet right now !
pop ecx edx ebx
mov word [edx + ICMP_Packet.Checksum], ax
jmp ETH_sender ; Send the reply
jmp NET_send ; Send the reply
; and return to caller of this proc
@ -222,12 +224,12 @@ ICMP_handler: ;TODO: works only on pure ethernet right now !
.try_more:
mov ax , [edx + ICMP_Packet.Identifier]
.next_socket:
mov esi, [esi + SOCKET_head.NextPtr]
mov esi, [esi + SOCKET.NextPtr]
or esi, esi
jz .dump
cmp [esi + SOCKET_head.Type], IP_PROTO_ICMP
cmp [esi + SOCKET.Type], IP_PROTO_ICMP
jne .next_socket
cmp [esi + SOCKET_head.end + IPv4_SOCKET.end + ICMP_SOCKET.Identifier], ax
cmp [esi + ICMP_SOCKET.Identifier], ax
jne .next_socket
call IPv4_dest_to_dev
@ -237,7 +239,7 @@ ICMP_handler: ;TODO: works only on pure ethernet right now !
DEBUGF 1,"Found valid ICMP packet for socket %x\n", esi
lea ebx, [esi + SOCKET_head.lock]
lea ebx, [esi + SOCKET.lock]
call wait_mutex
; Now, assign data to socket. We have socket address in esi.
@ -249,7 +251,7 @@ ICMP_handler: ;TODO: works only on pure ethernet right now !
add esp, 4
sub edx, esi
mov edi, edx
jmp socket_internal_receiver
;;; jmp SOCKET_input
.dump:
DEBUGF 1,"ICMP_Handler - dumping\n"
@ -260,59 +262,6 @@ ICMP_handler: ;TODO: works only on pure ethernet right now !
ret
;-----------------------------------------------------------------
;
; ICMP_Handler_fragments:
;
; Called by IP_handler,
; this procedure will send reply's to ICMP echo's etc
;
; IN: Pointer to buffer in [esp]
; size of buffer in [esp+4]
; pointer to device struct in ebx
; ICMP Packet size in ecx
; pointer to ICMP Packet data in edx
; OUT: /
;
;-----------------------------------------------------------------
align 4
ICMP_handler_fragments: ; works only on pure ethernet right now !
DEBUGF 1,"ICMP_Handler_fragments - start\n"
cmp ecx, 65500
jg .dump
cmp byte [edx + ICMP_Packet.Type], ICMP_ECHO ; Is this an echo request? discard if not
jne .dump
mov esi, [esp]
sub ecx, ICMP_Packet.Data
mov eax, [esi + IPv4_Packet.SourceAddress]
mov ebx, [esi + IPv4_Packet.DestinationAddress]
push word [esi + IPv4_Packet.Identification]
mov di , [edx + ICMP_Packet.Identifier]
shl edi, 16
mov di , [edx + ICMP_Packet.SequenceNumber]
mov esi, edx
add esi, ICMP_Packet.Data
pop dx
shl edx, 16
mov dx , ICMP_ECHOREPLY shl 8 + 0 ; Type + Code
call ICMP_create_packet
.dump:
DEBUGF 1,"ICMP_Handler_fragments - end\n"
call kernel_free
add esp, 4 ; pop (balance stack)
ret
;-----------------------------------------------------------------
;
; Note: ICMP only works on top of IP protocol :)
@ -330,7 +279,7 @@ ICMP_handler_fragments: ; works only on pure ethernet right now !
;
;-----------------------------------------------------------------
align 4
ICMP_create_packet:
ICMP_output:
DEBUGF 1,"Create ICMP Packet\n"
@ -341,9 +290,7 @@ ICMP_create_packet:
shr edx, 16
call IPv4_create_packet
cmp edi, -1
je .exit
jz .exit
DEBUGF 1,"full icmp packet size: %u\n", edx
@ -372,7 +319,7 @@ ICMP_create_packet:
and cx , 3
rep movsb
sub edi, edx ;; TODO: find a better way to remember start of packet
sub edi, edx ;;; TODO: find a better way to remember start of packet
mov ecx, [ebx + ETH_DEVICE.transmit]
push edx edi ecx
DEBUGF 1,"Sending ICMP Packet\n"

View File

@ -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 ;;
;; ;;
;; queue.inc ;;
@ -14,7 +14,7 @@
$Revision$
; The Queues implemented by these macros for a sort of ring-buffer.
; The Queues implemented by these macros form a ring-buffer.
; The data to these queue's always looks like this:
;
; At top, you have the queue struct, wich has the size (number of currently queued packets, read and write pointers.

File diff suppressed because it is too large Load Diff

View File

@ -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_OLD__ equ __DEBUG_LEVEL__
__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,85 +49,88 @@ AF_INET4 equ 2
;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
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 {
virtual at 0
add byte [reg + 3], 1
adc byte [reg + 2], 0
adc byte [reg + 1], 0
adc byte [reg], 0
NET_DEVICE:
.type dd ?
.end:
}
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
}
end virtual
; Exactly as it says..
macro pseudo_random reg {
add reg, [esp]
rol reg, 5
xor reg, [timer_ticks]
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 "tcp.inc"
include "udp.inc"
include "icmp.inc"
include "udp.inc"
include "tcp.inc"
include "socket.inc"
align 4
uglobal
NET_RUNNING dd ?
NET_DRV_LIST rd MAX_NET_DEVICES
endg
;-----------------------------------------------------------------
;
@ -139,28 +145,37 @@ include "icmp.inc"
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,41 +184,230 @@ stack_init:
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:
; Test for 1 second tick
mov al, 0
out 0x70, al
in al, 0x71
cmp al, [last_1sTick]
je .exit
mov [last_1sTick], al
inc [net_tmr_count]
cmp [net_tmr_count], 50
je .500ms
cmp [net_tmr_count], 100
jne .exit
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
@ -333,7 +537,7 @@ sys_network:
cmp ebx, -1
jne @f
mov eax, [ETH_RUNNING]
mov eax, [NET_RUNNING]
jmp .return
@@:
@ -344,12 +548,12 @@ sys_network:
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 @@ sys_network:
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 @@ sys_network:
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 @@ sys_network:
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 @@ sys_network:
;----------------------------------------------------------------
;
; System Function To work with Protocols (75)
; System function to work with protocols (75)
;
;----------------------------------------------------------------
align 4
@ -417,8 +621,8 @@ sys_protocols:
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 @@ sys_protocols:
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

File diff suppressed because it is too large Load Diff

View File

@ -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 ;;
;; ;;
;; UDP.INC ;;
@ -55,12 +55,11 @@ UDP_init:
ret
;-----------------------------------------------------------------
;
; UDP_Handler:
; UDP_input:
;
; Called by IPv4_handler,
; Called by IPv4_input,
; this procedure will inject the udp data diagrams in the application sockets.
;
; IN: Pointer to buffer in [esp]
@ -76,23 +75,20 @@ UDP_init:
;
;-----------------------------------------------------------------
align 4
UDP_handler:
UDP_input:
DEBUGF 1,"UDP_Handler, checksum:%x, size:%u\n", [edx+UDP_Packet.Checksum]:4, ecx
DEBUGF 1,"UDP_input, size:%u\n", ecx
; First validate, checksum:
cmp [edx + UDP_Packet.Checksum], 0
jz .no_checksum
xchg edi, esi ; save ipv4 source address so we can look it up later
xchg edi, esi ; save ipv4 source address to edi so we can use it later
push edx
push esi
push edi
push esi edi
mov esi, edx
call UDP_checksum ; this destroys edx, ecx and esi (but not edi! :)
call UDP_checksum ; this destroys edx, ecx and esi (but not edi...)
pop edx
cmp [edx + UDP_Packet.Checksum], 0
@ -108,76 +104,64 @@ UDP_handler:
mov eax, net_sockets
.try_more:
mov si , [edx + UDP_Packet.DestinationPort] ; get the local port from the IP Packet's UDP header
rol si , 8
.next_socket:
mov eax, [eax + SOCKET_head.NextPtr]
mov eax, [eax + SOCKET.NextPtr]
or eax, eax
jz .dump
cmp [eax + SOCKET_head.Domain], AF_INET4
cmp [eax + SOCKET.Domain], AF_INET4
jne .next_socket
cmp [eax + SOCKET_head.Type], IP_PROTO_UDP
cmp [eax + SOCKET.Type], IP_PROTO_UDP
jne .next_socket
cmp [eax + SOCKET_head.end + IPv4_SOCKET.end + UDP_SOCKET.LocalPort], si
cmp [eax + UDP_SOCKET.LocalPort], si
jne .next_socket
DEBUGF 1,"found socket with matching domain, type and localport\n"
DEBUGF 1,"using socket: %x\n", eax
; For dhcp, we must allow any remote server to respond.
; I will accept the first incoming response to be the one
; I bind to, if the socket is opened with a destination IP address of
; 255.255.255.255
cmp [eax + SOCKET_head.end + IPv4_SOCKET.RemoteIP], 0xffffffff
je .ok1
;;; TODO: when packet is processed, check more sockets!
cmp [eax + SOCKET_head.end + IPv4_SOCKET.RemoteIP], edi ; edi is IPv4 destination address
jne .try_more ; Quit if the source IP is not valid, check for more sockets with this IP/PORT combination
cmp [eax + IP_SOCKET.RemoteIP], 0xffffffff
je @f
cmp [eax + IP_SOCKET.RemoteIP], edi ; edi is the packets source address
jne .try_more
@@:
DEBUGF 1,"Remote Ip matches\n"
.ok1:
cmp [eax + SOCKET_head.end + IPv4_SOCKET.end + UDP_SOCKET.firstpacket], 0
cmp [eax + UDP_SOCKET.firstpacket], 0
jz .updateport
mov si, [edx + UDP_Packet.SourcePort]
cmp [eax + SOCKET_head.end + IPv4_SOCKET.end + UDP_SOCKET.RemotePort], si
rol si, 8
cmp [eax + UDP_SOCKET.RemotePort], si
jne .dump
push ebx
lea ebx, [eax + SOCKET_head.lock]
lea ebx, [eax + SOCKET.lock]
call wait_mutex
pop ebx
.ok2:
.updatesock:
inc [UDP_PACKETS_RX]
DEBUGF 1,"Found valid UDP packet for socket %x\n", eax
lea esi, [edx + UDP_Packet.Data]
movzx ecx, [edx + UDP_Packet.Length]
rol cx , 8
sub cx , UDP_Packet.Data
inc [UDP_PACKETS_RX]
pop edi
add esp, 4
sub esi, edi
xchg esi, edi
jmp socket_internal_receiver
jmp SOCKET_input
.updateport:
push ebx
lea ebx, [eax + SOCKET_head.lock]
lea ebx, [eax + SOCKET.lock]
call wait_mutex
pop ebx
mov si, [edx + UDP_Packet.SourcePort]
DEBUGF 1,"Changing remote port to: %x\n", si
mov [eax + SOCKET_head.end + IPv4_SOCKET.end + UDP_SOCKET.RemotePort], si
inc [eax + SOCKET_head.end + IPv4_SOCKET.end + UDP_SOCKET.firstpacket]
rol si, 8
DEBUGF 1,"Changing remote port to: %u\n", si
mov [eax + UDP_SOCKET.RemotePort], si
inc [eax + UDP_SOCKET.firstpacket]
jmp .ok2
jmp .updatesock
.checksum_mismatch:
@ -202,7 +186,7 @@ UDP_handler:
;-----------------------------------------------------------------
;
; UDP_socket_send
; UDP_output
;
; IN: eax = socket pointer
; ecx = number of bytes to send
@ -211,27 +195,31 @@ UDP_handler:
;-----------------------------------------------------------------
align 4
UDP_socket_send:
UDP_output:
mov edx, dword [eax + SOCKET_head.end + IPv4_SOCKET.end + UDP_SOCKET.LocalPort] ; load local port and remote port at once
DEBUGF 1,"local port: %x, remote port: %x\n",\
[eax + SOCKET_head.end + IPv4_SOCKET.end + UDP_SOCKET.LocalPort]:4,\
[eax + SOCKET_head.end + IPv4_SOCKET.end + UDP_SOCKET.RemotePort]:4
mov ebx, [eax + SOCKET_head.end + IPv4_SOCKET.LocalIP]
mov eax, [eax + SOCKET_head.end + IPv4_SOCKET.RemoteIP]
DEBUGF 1,"UDP_output: socket:%x, bytes: %u, data ptr: %x\n", eax, ecx, esi
DEBUGF 1,"Create UDP Packet (size=%u)\n",ecx
mov dx, [eax + UDP_SOCKET.RemotePort]
DEBUGF 1,"remote port: %u\n", dx
rol dx, 8
rol edx, 16
mov dx, [eax + UDP_SOCKET.LocalPort]
DEBUGF 1,"local port: %u\n", dx
rol dx, 8
mov ebx, [eax + IP_SOCKET.LocalIP]
mov eax, [eax + IP_SOCKET.RemoteIP]
mov di , IP_PROTO_UDP
sub esp, 8 ; Data ptr and data size will be placed here
add ecx, UDP_Packet.Data
; TODO: fill in: dx = fragment id
;;; TODO: fragment id
push edx esi
call IPv4_create_packet ; TODO: figure out a way to choose between IPv4 and IPv6
cmp edi, -1
je .fail
call IPv4_create_packet
jz .fail
mov [esp + 8], eax ; pointer to buffer start
mov [esp + 8 + 4], edx ; buffer size
@ -251,7 +239,7 @@ UDP_socket_send:
rep movsb
pop ecx edi
pop dword [edi + UDP_Packet.SourcePort] ; fill in both portnumbers
pop dword [edi + UDP_Packet.SourcePort]
mov [edi + UDP_Packet.Checksum], 0 ; set it to zero, to calculate checksum
; Checksum
@ -263,10 +251,10 @@ UDP_socket_send:
inc [UDP_PACKETS_TX]
DEBUGF 1,"Sending UDP Packet to device %x\n", ebx
jmp ETH_sender
jmp NET_send
.fail:
; todo: queue the packet
add esp, 8+8
ret
@ -275,7 +263,7 @@ UDP_socket_send:
;-----------------------------------------------------------------
;
; checksum_udp
; UDP_checksum
;
; This is the fast procedure to create or check a UDP header
; - To create a new checksum, the checksum field must be set to 0 before computation