- 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 12, 1 ; start of draw
mcall 0, dword [Form], dword [Form + 4], 0x13ffffff, 0x805080d0, title 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 call Get_PCI_Info ; get pci version and last bus, scan for and draw each pci device
cmp edx, 20 shl 16 + 110 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
push 0 ; sin_zero push 0 ; sin_zero
push esi ; sin_addr 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 ; sin_family and sin_port in network byte order
; 8c. Connect. ; 8c. Connect.
mcall 74, 4, , esp, sizeof.sockaddr_in mcall 74, 4, , esp, sizeof.sockaddr_in

View File

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

View File

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

View File

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

View File

@ -131,29 +131,8 @@ START: ; start of execution
mcall 40, 1 shl 7 ; network event mcall 40, 1 shl 7 ; network event
; eth.set_network_drv 0x00000383
DEBUGF 1,">Zero-config service:\n" 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 mcall 75, 1337 shl 16 + 4
cmp eax, -1 cmp eax, -1
@ -254,6 +233,7 @@ buildRequest: ; Creates a DHCP request packet.
test eax,eax test eax,eax
jz apipa jz apipa
;;; todo: skip this bullcrap
mov edi, eax mov edi, eax
mov ecx, BUFFER mov ecx, BUFFER
@ -261,12 +241,14 @@ buildRequest: ; Creates a DHCP request packet.
cld cld
rep stosb rep stosb
;; todo: put this in a buffer instead of writing bytes and words!
mov edx,[dhcpMsg] mov edx,[dhcpMsg]
mov [edx], byte 0x01 ; Boot request mov [edx], byte 0x01 ; Boot request
mov [edx+1], byte 0x01 ; Ethernet mov [edx+1], byte 0x01 ; Ethernet
mov [edx+2], byte 0x06 ; Ethernet h/w len 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 eax,[currTime]
mov [edx+8], eax ; secs, our uptime mov [edx+8], eax ; secs, our uptime
mov [edx+10], byte 0x80 ; broadcast flag set mov [edx+10], byte 0x80 ; broadcast flag set
@ -274,7 +256,7 @@ buildRequest: ; Creates a DHCP request packet.
mov [edx+28],dword eax mov [edx+28],dword eax
mov ax, word [MAC+4] ; last 2 bytes of MAC mov ax, word [MAC+4] ; last 2 bytes of MAC
mov [edx+32],word ax 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 [edx+240], word 0x0135 ; option DHCP msg type
mov al, [dhcpMsgType] mov al, [dhcpMsgType]
mov [edx+240+2], al mov [edx+240+2], al
@ -313,7 +295,6 @@ send_request:
mcall 23, TIMEOUT*10 ; wait for data mcall 23, TIMEOUT*10 ; wait for data
read_data: ; we have data - this will be the response read_data: ; we have data - this will be the response
mcall 74, 7, [socketNum], [dhcpMsg], BUFFER ; read data from socket mcall 74, 7, [socketNum], [dhcpMsg], BUFFER ; read data from socket
DEBUGF 1,"->%d bytes received\n", eax DEBUGF 1,"->%d bytes received\n", eax
@ -464,7 +445,7 @@ pr001:
pr_exit: pr_exit:
; DEBUGF 1,"Sending ARP announce\n" ; DEBUGF 1,"Sending ARP announce\n"
; eth.ARP_ANNOUNCE [dhcpClientIP] ; send an ARP announce packet ;;;
jmp close jmp close
@ -572,7 +553,7 @@ str_type db 'type',0
sockaddr1: sockaddr1:
dw AF_INET4 dw AF_INET4
dw 68 shl 8 ; local port dw 68 ; local port
dd 0 ; local IP dd 0 ; local IP
rb 10 rb 10
@ -581,7 +562,7 @@ sockaddr1:
sockaddr2: sockaddr2:
dw AF_INET4 dw AF_INET4
dw 67 shl 8 ; destination port dw 67 ; destination port
dd -1 ; destination IP dd -1 ; destination IP
rb 10 rb 10

View File

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

View File

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

View File

@ -545,7 +545,8 @@ proc service_proc stdcall, ioctl:dword
.register: .register:
call EthRegDev mov [device.type], NET_TYPE_ETH
call NetRegDev
cmp eax, -1 cmp eax, -1
je .destroy je .destroy
@ -566,7 +567,7 @@ proc service_proc stdcall, ioctl:dword
.find_devicenum: .find_devicenum:
DEBUGF 1,"Trying to find device number of already registered device\n" 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 ; into a device number in edi
mov eax, edi ; Application wants it in eax instead mov eax, edi ; Application wants it in eax instead
DEBUGF 1,"Kernel says: %u\n", eax 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 mov [DEVICE_LIST+4*eax], ebx
inc [DEVICES] 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 cmp eax, -1
jz .err jz .err
ret 4 ret 4
@ -320,7 +322,7 @@ proc service_proc stdcall, ioctl:dword
.find_devicenum: .find_devicenum:
DEBUGF 1,"Trying to find device number of already registered device\n" DEBUGF 1,"Trying to find device number of already registered device\n"
mov ebx, eax 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 ; into a device number in edi
mov eax, edi ; Application wants it in eax instead mov eax, edi ; Application wants it in eax instead
DEBUGF 1,"Kernel says: %u\n", eax 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" DEBUGF 1,"Trying to find device number of already registered device\n"
mov ebx, eax 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 ; into a device number in edi
mov eax, edi ; Application wants it in eax instead mov eax, edi ; Application wants it in eax instead
DEBUGF 1,"Kernel says: %u\n", eax 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 ;; ;; Distributed under terms of the GNU General Public License ;;
;; ;; ;; ;;
;; Realtek 8139 driver for KolibriOS ;; ;; Realtek 8139 driver for KolibriOS ;;
@ -368,7 +368,9 @@ proc service_proc stdcall, ioctl:dword
inc [RTL8139_DEV] ; inc [RTL8139_DEV] ;
call EthRegDev mov [device.type], NET_TYPE_ETH
call NetRegDev
cmp eax, -1 cmp eax, -1
je .destroy je .destroy
@ -378,8 +380,7 @@ proc service_proc stdcall, ioctl:dword
.find_devicenum: .find_devicenum:
DEBUGF 2,"Trying to find device number of already registered device\n" DEBUGF 2,"Trying to find device number of already registered device\n"
mov ebx, eax call NetPtrToNum ; This kernel procedure converts a pointer to device struct in ebx
call EthStruc2Dev ; This kernel procedure converts a pointer to device struct in ebx
; into a device number in edi ; into a device number in edi
mov eax, edi ; Application wants it in eax instead mov eax, edi ; Application wants it in eax instead
DEBUGF 2,"Kernel says: %u\n", eax DEBUGF 2,"Kernel says: %u\n", eax
@ -445,19 +446,22 @@ probe:
shr ah , 2 shr ah , 2
shr ax , 6 shr ax , 6
and al , 01111111b and al , 01111111b
mov ecx, HW_VER_ARRAY_SIZE-1 mov ecx, HW_VER_ARRAY_SIZE-1
.chip_ver_loop: .chip_ver_loop:
cmp al , [hw_ver_array + ecx] cmp al , [hw_ver_array + ecx]
je .chip_ver_found je .chip_ver_found
dec ecx dec ecx
jns .chip_ver_loop jns .chip_ver_loop
xor cl , cl ; default RTL8139 .unknown:
mov ecx, 8
.chip_ver_found: .chip_ver_found:
cmp ecx, 8
jg .unknown
mov [device.hw_ver_id], cl mov [device.hw_ver_id], cl
shl ecx, 2 mov ecx, [crosslist + ecx*4]
add ecx, crosslist
mov ecx, [ecx]
mov [device.name], ecx mov [device.name], ecx
DEBUGF 2,"Chip version: %s\n", 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_6 db 'Realtek 8139D',0
device_7 db 'Realtek 8139CP',0 device_7 db 'Realtek 8139CP',0
device_8 db 'Realtek 8101',0 device_8 db 'Realtek 8101',0
device_unknown db 'Unknown RTL8139 clone', 0
crosslist dd device_1 crosslist dd device_1
dd device_2 dd device_2
@ -1232,6 +1237,7 @@ crosslist dd device_1
dd device_6 dd device_6
dd device_7 dd device_7
dd device_8 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 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 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_RTL8139D
db VER_RTL8139CP db VER_RTL8139CP
db VER_RTL8101 db VER_RTL8101
db 0
HW_VER_ARRAY_SIZE = $-hw_ver_array HW_VER_ARRAY_SIZE = $-hw_ver_array

View File

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

View File

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

View File

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

View File

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

View File

@ -36,23 +36,11 @@ format MS COFF
include 'proc32.inc' include 'proc32.inc'
include 'imports.inc' include 'imports.inc'
include 'fdo.inc' include 'fdo.inc'
include 'netdrv.inc'
public START public START
public version 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_RX_DESC equ 4 ;* Number of RX descriptors *
NUM_TX_DESC equ 1 ;* Number of TX descriptors * NUM_TX_DESC equ 1 ;* Number of TX descriptors *
RX_BUFF_SZ equ 1520 ;* Buffer size for each Rx buffer * 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 TOTAL_BUFFERS_SIZE equ NUM_RX_DESC*RX_BUFF_SZ + NUM_TX_DESC*TX_BUFF_SZ
struc ETH_DEVICE { virtual at 0
; pointers to procedures device:
.unload dd ?
.reset dd ? ETH_DEVICE
.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 ?
; device specific ; device specific
.io_addr dd ? .io_addr dd ?
.pci_bus db ? .pci_bus db ?
@ -91,7 +67,7 @@ align 4
.txd: times (3 * NUM_TX_DESC) dd 0 .txd: times (3 * NUM_TX_DESC) dd 0
.rxd: times (3 * NUM_RX_DESC) dd 0 .rxd: times (3 * NUM_RX_DESC) dd 0
.size: .size:
} end virtual
; First page is designated to ETH_DEVICE, buffers start from second ; First page is designated to ETH_DEVICE, buffers start from second
ALLOCATION_SIZE = ((device.size+0FFFh) and not 0FFFh) + TOTAL_BUFFERS_SIZE 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 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_HEADER_TYPE equ 0x0e ;8 bit
PCI_BASE_ADDRESS_0 equ 0x10 ;32 bit PCI_BASE_ADDRESS_0 equ 0x10 ;32 bit
@ -238,7 +211,9 @@ service_proc:
jnz .destroy jnz .destroy
; 4n. If device was successfully initialized, register it for the kernel. ; 4n. If device was successfully initialized, register it for the kernel.
call EthRegDev mov [device.type], NET_TYPE_ETH
call NetRegDev
cmp eax, -1 cmp eax, -1
je .destroy je .destroy
@ -248,7 +223,7 @@ service_proc:
.find_devicenum: .find_devicenum:
mov ebx, eax 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 ; into a device number in edi
mov eax, edi ; Application wants it in eax instead mov eax, edi ; Application wants it in eax instead
ret 4 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: ;; PROGRAMMING:
;; Ivan Poddubny ;; Ivan Poddubny
;; Marat Zakiyanov (Mario79) ;; 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 ;; ;; Distributed under terms of the GNU General Public License ;;
;; ;; ;; ;;
;; ARP.INC ;; ;; ARP.INC ;;
@ -12,7 +12,7 @@
;; Written by hidnplayr@kolibrios.org ;; ;; Written by hidnplayr@kolibrios.org ;;
;; ;; ;; ;;
;; GNU GENERAL PUBLIC LICENSE ;; ;; 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 mov eax, [IP_LIST+4*edi] ; senderIP
push eax push eax
mov edi, [ETH_DRV_LIST + 4*edi] mov edi, [NET_DRV_LIST + 4*edi]
lea eax, [edi + ETH_DEVICE.mac] lea eax, [edi + ETH_DEVICE.mac]
mov ebx, ETH_BROADCAST mov ebx, ETH_BROADCAST
mov ecx, 60 ; minimum packet size mov ecx, 60 ; minimum packet size
mov edx, edi ;;; mov edx, edi ;;;
mov di , ETHER_ARP mov di , ETHER_ARP
call ETH_create_packet call ETH_create_packet
cmp edi, -1 jz .exit
je .exit
mov ecx, eax mov ecx, eax
@ -275,7 +274,7 @@ ARP_create_request:
DEBUGF 1,"ARP Packet for device %x created successfully\n", ebx DEBUGF 1,"ARP Packet for device %x created successfully\n", ebx
push edx ecx push edx ecx
jmp ETH_sender jmp NET_send
.exit: .exit:
add esp, 8 add esp, 8
@ -523,7 +522,7 @@ ARP_handler:
cmp word [edx + ARP_Packet.Opcode], ARP_REQ_OPCODE ; Is this a request packet? cmp word [edx + ARP_Packet.Opcode], ARP_REQ_OPCODE ; Is this a request packet?
jne .exit jne .exit
call ETH_struc2dev call NET_ptr_to_num
DEBUGF 1,"ARP Request packet through device: %u\n", edi DEBUGF 1,"ARP Request packet through device: %u\n", edi
inc [ARP_PACKETS_RX+4*edi] inc [ARP_PACKETS_RX+4*edi]
cmp edi, -1 cmp edi, -1
@ -549,7 +548,7 @@ ARP_handler:
movsd ; Move sender IP to Dest IP movsd ; Move sender IP to Dest IP
pop esi pop esi
mov esi, [ETH_DRV_LIST + 4*esi] mov esi, [NET_DRV_LIST + 4*esi]
lea esi, [esi + ETH_DEVICE.mac] lea esi, [esi + ETH_DEVICE.mac]
lea edi, [edx + ARP_Packet.SenderMAC] lea edi, [edx + ARP_Packet.SenderMAC]
movsd ; Copy MAC address from in MAC_LIST movsd ; Copy MAC address from in MAC_LIST
@ -573,7 +572,7 @@ ARP_handler:
DEBUGF 1,"ARP_Handler - Sending reply \n" DEBUGF 1,"ARP_Handler - Sending reply \n"
jmp ETH_sender ; And send it! jmp NET_send ; And send it!
.exit: .exit:
call kernel_free 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 ;; ;; Distributed under terms of the GNU General Public License ;;
;; ;; ;; ;;
;; IPv4.INC ;; ;; IPv4.INC ;;
@ -18,16 +18,13 @@
$Revision$ $Revision$
; IP underlying protocols numbers MAX_FRAGMENTS equ 64
ETHER_IPv4 equ 0x0008 ; Reversed from 0800 for intel
MAX_FRAGMENTS equ 16
MAX_IP equ MAX_NET_DEVICES MAX_IP equ MAX_NET_DEVICES
IP_MAX_INTERFACES equ MAX_IP
struct IPv4_Packet struct IPv4_Packet
.VersionAndIHL db ? ; Version[0-3 bits] and IHL(header length)[4-7 bits] .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 ? .TotalLength dw ?
.Identification dw ? .Identification dw ?
.FlagsAndFragmentOffset dw ? ; Flags[0-2] and FragmentOffset[3-15] .FlagsAndFragmentOffset dw ? ; Flags[0-2] and FragmentOffset[3-15]
@ -58,13 +55,15 @@ ends
align 4 align 4
uglobal uglobal
BROADCAST dd ?
IP_LIST rd MAX_IP IP_LIST rd MAX_IP
SUBNET_LIST rd MAX_IP SUBNET_LIST rd MAX_IP
DNS_LIST rd MAX_IP DNS_LIST rd MAX_IP
GATEWAY_LIST rd MAX_IP GATEWAY_LIST rd MAX_IP
IP_PACKETS_TX rd MAX_IP IP_PACKETS_TX rd MAX_IP
IP_PACKETS_RX rd MAX_IP IP_PACKETS_RX rd MAX_IP
FRAGMENT_LIST rb MAX_FRAGMENTS*FRAGMENT_slot.size FRAGMENT_LIST rb MAX_FRAGMENTS*FRAGMENT_slot.size
endg endg
@ -83,11 +82,11 @@ align 4
IPv4_init: IPv4_init:
or eax, -1 or eax, -1
mov edi, BROADCAST mov edi, IP_LIST
mov ecx, 4*MAX_IP+1 mov ecx, 4*MAX_IP
rep stosd rep stosd
xor eax, eax inc eax
mov edi, FRAGMENT_LIST mov edi, FRAGMENT_LIST
mov ecx, FRAGMENT_slot.size*MAX_FRAGMENTS/4 + 2*MAX_IP mov ecx, FRAGMENT_slot.size*MAX_FRAGMENTS/4 + 2*MAX_IP
rep stosd rep stosd
@ -114,10 +113,12 @@ IPv4_init:
;----------------------------------------------------------------- ;-----------------------------------------------------------------
align 4 align 4
IPv4_handler: ; TODO: implement handler for IP options IPv4_handler: ; TODO: implement handler for IP options
; TODO2: add code for IPv4 sockets (raw sockets) ; TODO2: add code for raw sockets
DEBUGF 1,"IP_Handler - start\n"
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 ; 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) cmp al , 0x05 ; IHL!= 5*4(20 bytes)
jnz .has_options jnz .has_options
;------------------------------- ;-------------------------------
; Now, re-calcualte the checksum ; Now, re-calculate the checksum
; Re-calculate checksum
push edx ebx push edx ebx
mov esi, edx mov esi, edx
call IPv4_checksum call IPv4_checksum
pop ebx edx pop ebx edx
; now see if it was correct
cmp [edx + IPv4_Packet.HeaderChecksum], 0 cmp [edx + IPv4_Packet.HeaderChecksum], 0
jne .dump ; if checksum isn't valid then dump packet jne .dump ; if checksum isn't valid then dump packet
DEBUGF 1,"IPv4 Checksum is correct\n" 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] ; check if it matches local ip
mov edi, BROADCAST
mov ecx, MAX_IP+1
.find_ip_loop: mov eax, dword[IP_LIST+edi]
cmp eax, dword [edi] cmp [edx + IPv4_Packet.DestinationAddress], eax
jz .ip_ok je .ip_ok
add edi, 4
dec ecx
jnz .find_ip_loop
; it was not on the list, perhaps it's a loopback ? ; check for broadcast
mov eax, dword[SUBNET_LIST+edi]
not eax not eax
test eax, 127 shl 24 ; 127.x.x.x or eax, dword[IP_LIST+edi]
jz .ip_ok 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" DEBUGF 2,"Destination address does not match!\n"
jmp .dump jmp .dump
;------------------------
;--------------------------------------------------- ; Now we can update stats
; Now we can update stats and find the device number
.ip_ok: .ip_ok:
call ETH_struc2dev ; TODO: make this work on other protocols too! inc [IP_PACKETS_RX+edi]
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
;---------------------------------- ;----------------------------------
; Check if the packet is fragmented ; 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 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 jnz .is_last_fragment
;------------------------------------------------------------------- ;-------------------------------------------------------------------
; No, it's just a regular IP packet, pass it to the higher protocols ; 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 .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 movzx eax, byte [edx + IPv4_Packet.VersionAndIHL] ; Calculate Header length by using IHL field
and eax, 0x0000000F ; and eax, 0x0000000f ;
shl eax, 2 ; shl eax, 2 ;
movzx ecx, word [edx + IPv4_Packet.TotalLength] ; Calculate length of encapsulated Packet movzx ecx, word [edx + IPv4_Packet.TotalLength] ; Calculate length of encapsulated Packet
xchg cl , ch ; xchg cl , ch ;
@ -220,13 +224,13 @@ IPv4_handler: ; TODO: implement handler for IP options
pop edx ; Offset to data (tcp/udp/icmp/.. Packet) pop edx ; Offset to data (tcp/udp/icmp/.. Packet)
cmp al , IP_PROTO_TCP cmp al , IP_PROTO_TCP
je TCP_handler je TCP_input
cmp al , IP_PROTO_UDP cmp al , IP_PROTO_UDP
je UDP_handler je UDP_input
cmp al , IP_PROTO_ICMP cmp al , IP_PROTO_ICMP
je ICMP_handler je ICMP_input
DEBUGF 2,"unknown Internet protocol: %u\n", al DEBUGF 2,"unknown Internet protocol: %u\n", al
@ -351,7 +355,7 @@ IPv4_handler: ; TODO: implement handler for IP options
cmp esi, -1 cmp esi, -1
jne .count_bytes 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 [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.NextPtr], -1
mov [esi + FRAGMENT_entry.PrevPtr], edi mov [esi + FRAGMENT_entry.PrevPtr], edi
@ -463,13 +467,15 @@ IPv4_handler: ; TODO: implement handler for IP options
; ;
; find fragment slot ; 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 ; OUT: pointer to slot in edi, -1 on error
; ;
;----------------------------------------------------------------- ;-----------------------------------------------------------------
align 4 align 4
IPv4_find_fragment_slot: IPv4_find_fragment_slot:
;;; TODO: the RFC says we should check protocol number too
push eax ebx ecx edx push eax ebx ecx edx
mov ax , word [edx + IPv4_Packet.Identification] mov ax , word [edx + IPv4_Packet.Identification]
mov ecx, MAX_FRAGMENTS mov ecx, MAX_FRAGMENTS
@ -514,7 +520,7 @@ IPv4_decrease_fragment_ttls:
dec [esi + FRAGMENT_slot.ttl] dec [esi + FRAGMENT_slot.ttl]
jnz .try_next jnz .try_next
DEBUGF 1,"Fragment slot timed-out!\n" 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: .try_next:
add esi, 4 add esi, 4
loop .loop 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 ; Create_IPv4_Packet
; ;
; IN: eax = dest ip ; IN: eax = dest ip
; ebx = source ip ; ebx = source ip
; ecx = data length ; ecx = data length
; dx = fragment id ; dx = fragment id ;;;;
; di = protocol ; di = protocol
; ;
; OUT: eax = pointer to buffer start ; OUT: eax = pointer to buffer start
; ebx = pointer to device struct (needed for sending procedure) ; ebx = pointer to device struct (needed for sending procedure)
; ecx = unchanged (packet size of embedded data) ; ecx = unchanged (packet size of embedded data)
; edx = size of complete buffer ; edx = size of complete buffer
; esi = pointer to sending procedure ; edi = pointer to start of data (0 on error)
; edi = pointer to start of data (-1 on error)
; ;
;----------------------------------------------------------------- ;;; TODO: create fragmented packets ;------------------------------------------------------------------
align 4 align 4
IPv4_create_packet: IPv4_create_packet:
DEBUGF 1,"Create IPv4 Packet (size=%u)\n", ecx DEBUGF 1,"Create IPv4 Packet (size=%u)\n", ecx
cmp ecx, 1480 cmp ecx, 65500 ; Max IPv4 packet size
jg .exit_ jg .exit_
test ebx, ebx ; if dest ip = 0 test ebx, ebx ; if source ip = 0
jnz .ip_ok ; and local ip is valid jnz .ip_ok ; and local ip is valid
; use local ip instead ; use local ip instead
cmp [IP_LIST],0xffffffff ; cmp [IP_LIST],0xffffffff ;
@ -582,16 +613,17 @@ IPv4_create_packet:
.send: .send:
call IPv4_dest_to_dev call IPv4_dest_to_dev
inc [IP_PACKETS_TX+4*edi] 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] lea eax, [edx + ETH_DEVICE.mac]
mov ebx, esp mov ebx, esp
mov ecx, [esp+18] ;; 18 or 22 ?? mov ecx, [esp+18] ;; 18 or 22 ??
add ecx, IPv4_Packet.DataOrOptional add ecx, IPv4_Packet.DataOrOptional
mov di , ETHER_IPv4 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 add esp, 6
cmp edi, -1 test edi, edi
je .exit jz .exit
mov [edi + IPv4_Packet.VersionAndIHL], 0x45 ; IPv4, normal length (no Optional header) mov [edi + IPv4_Packet.VersionAndIHL], 0x45 ; IPv4, normal length (no Optional header)
mov [edi + IPv4_Packet.TypeOfService], 0 mov [edi + IPv4_Packet.TypeOfService], 0
@ -622,12 +654,12 @@ IPv4_create_packet:
.not_found: .not_found:
DEBUGF 1,"Create IPv4 Packet - ARP entry not found!\n" DEBUGF 1,"Create IPv4 Packet - ARP entry not found!\n"
; TODO: QUEUE the packet to resend later! ;;;;;;
.exit: .exit:
add esp, 16 add esp, 16
.exit_: .exit_:
DEBUGF 1,"Create IPv4 Packet - failed\n" DEBUGF 1,"Create IPv4 Packet - failed\n"
or edi, -1 and edi, 0
ret 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 ;; ;; Distributed under terms of the GNU General Public License ;;
;; ;; ;; ;;
;; ETHERNET.INC ;; ;; ETHERNET.INC ;;
@ -16,17 +16,18 @@
$Revision$ $Revision$
MAX_ETH_DEVICES equ MAX_NET_DEVICES
ETH_QUEUE_SIZE equ 16 ETH_QUEUE_SIZE equ 16
struct ETH_FRAME struct ETH_FRAME
.DstMAC dp ? ; destination MAC-address [6 bytes] .DstMAC dp ? ; destination MAC-address
.SrcMAC dp ? ; source MAC-address [6 bytes] .SrcMAC dp ? ; source MAC-address
.Type dw ? ; type of the upper-layer protocol [2 bytes] .Type dw ? ; type of the upper-layer protocol
.Data: ; data [46-1500 bytes] .Data: ; data (46-1500 bytes for a normal packet)
ends ends
struct ETH_DEVICE virtual at NET_DEVICE.end
ETH_DEVICE:
.unload dd ? .unload dd ?
.reset dd ? .reset dd ?
.transmit dd ? .transmit dd ?
@ -39,18 +40,11 @@ struct ETH_DEVICE
.bytes_rx dq ? .bytes_rx dq ?
.packets_tx dd ? .packets_tx dd ?
.packets_rx dd ? .packets_rx dd ?
.mode dd ? ; This dword contains cable status (10mbit/100mbit, full/half duplex, auto negotiation or not,..) .mode dd ?
.name dd ? .name dd ?
.mac dp ? .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 align 4
iglobal iglobal
@ -60,13 +54,7 @@ endg
align 4 align 4
uglobal uglobal
ETH_RUNNING dd ? 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 endg
@ -83,126 +71,11 @@ endg
align 4 align 4
ETH_init: ETH_init:
xor eax, eax mov [ETH_RUNNING], 0
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
ret 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: ; ETH_Receiver:
@ -218,57 +91,8 @@ end if
;----------------------------------------------------------------- ;-----------------------------------------------------------------
align 4 align 4
ETH_receiver: 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 eax, [esp]
mov ecx, [esp+4] mov ecx, [esp+4]
;-----------------------------
DEBUGF 1,"ETH_Handler - size: %u\n", ecx DEBUGF 1,"ETH_Handler - size: %u\n", ecx
cmp ecx, 60 ; check packet length cmp ecx, 60 ; check packet length
@ -290,136 +114,23 @@ ETH_receiver:
DEBUGF 2,"ETH_Handler - dumping\n" DEBUGF 2,"ETH_Handler - dumping\n"
call kernel_free call kernel_free
add esp, 4 add esp, 4
.gohome:
ret ; return to get more from queue / to caller
align 4
ETH_handler:
ret 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 ; ETH_create_packet
; ;
; IN: pointer to source mac in eax ; IN: eax = pointer to source mac
; pointer to destination mac in ebx ; ebx = pointer to destination mac
; packet size in ecx ; ecx = packet size
; device number in edx ; edx = device number
; protocol in di ; di = protocol
; ;
; OUT: edi is -1 on error, pointer to buffer otherwise ; OUT: edi = 0 on error, pointer to buffer otherwise
; eax points to buffer start ; eax = buffer start
; ebx is pointer to device structure ; ebx = to device structure
; ecx is unchanged (packet size of embedded data) ; ecx = unchanged (packet size of embedded data)
; edx is size of complete buffer ; edx = size of complete buffer
; esi points to procedure wich needs to be called to send packet
; ;
;----------------------------------------------------------------- ;-----------------------------------------------------------------
align 4 align 4
@ -427,7 +138,7 @@ ETH_create_packet:
DEBUGF 1,"Creating Ethernet Packet (size=%u): \n", ecx DEBUGF 1,"Creating Ethernet Packet (size=%u): \n", ecx
cmp ecx, 1500 cmp ecx, 1500 ;;;
jg .exit jg .exit
push ecx di eax ebx edx push ecx di eax ebx edx
@ -436,13 +147,13 @@ ETH_create_packet:
push ecx push ecx
push ecx push ecx
call kernel_alloc call kernel_alloc
test eax, eax mov edi, eax
test edi, edi
jz .pop_exit jz .pop_exit
pop ecx pop ecx
pop edx pop edx
mov edi, eax
pop esi pop esi
movsd movsd
movsw movsw
@ -455,10 +166,9 @@ ETH_create_packet:
lea eax, [edi - ETH_FRAME.Data] ; Set eax to buffer start lea eax, [edi - ETH_FRAME.Data] ; Set eax to buffer start
mov edx, ecx ; Set ebx to complete buffer size mov edx, ecx ; Set ebx to complete buffer size
pop ecx pop ecx
mov esi, ETH_sender
xor ebx, ebx ;;;; TODO: Fixme 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 cmp edx, 46 + ETH_FRAME.Data ; If data size is less then 46, add padding bytes
jg .continue jg .continue
@ -471,12 +181,12 @@ ETH_create_packet:
.pop_exit: .pop_exit:
DEBUGF 2,"Out of ram space!!\n" DEBUGF 2,"Out of ram space!!\n"
add esp, 18 add esp, 18
or edi,-1 and edi, 0
ret ret
.exit: .exit:
DEBUGF 2,"Packet too large!\n" DEBUGF 2,"Packet too large!\n"
or edi, -1 and edi, 0
ret ret
@ -497,9 +207,20 @@ ETH_create_packet:
align 4 align 4
ETH_API: ETH_API:
cmp bh, MAX_NET_DEVICES
jg .error
movzx eax, bh movzx eax, bh
shl eax, 2 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 test bl, bl
jz .packets_tx ; 0 jz .packets_tx ; 0
dec bl dec bl
@ -512,39 +233,28 @@ ETH_API:
jz .read_mac ; 4 jz .read_mac ; 4
dec bl dec bl
jz .write_mac ; 5 jz .write_mac ; 5
dec bl
jz .in_queue ; 6
dec bl
jz .out_queue ; 7
.error: .error:
mov eax, -1 DEBUGF 2,"Device is not ethernet type\n"
or eax, -1
ret ret
.packets_tx: .packets_tx:
add eax, ETH_DRV_LIST
mov eax, dword [eax]
mov eax, dword [eax + ETH_DEVICE.packets_tx] mov eax, dword [eax + ETH_DEVICE.packets_tx]
ret ret
.packets_rx: .packets_rx:
add eax, ETH_DRV_LIST
mov eax, dword [eax]
mov eax, dword [eax + ETH_DEVICE.packets_rx] mov eax, dword [eax + ETH_DEVICE.packets_rx]
ret ret
.bytes_tx: .bytes_tx:
add eax, ETH_DRV_LIST
mov eax, dword [eax]
mov ebx, dword [eax + ETH_DEVICE.bytes_tx + 4] mov ebx, dword [eax + ETH_DEVICE.bytes_tx + 4]
mov eax, dword [eax + ETH_DEVICE.bytes_tx] mov eax, dword [eax + ETH_DEVICE.bytes_tx]
mov [esp+20+4], ebx ; TODO: fix this ugly code mov [esp+20+4], ebx ; TODO: fix this ugly code
ret ret
.bytes_rx: .bytes_rx:
add eax, ETH_DRV_LIST
mov eax, dword [eax]
mov ebx, dword [eax + ETH_DEVICE.bytes_rx + 4] mov ebx, dword [eax + ETH_DEVICE.bytes_rx + 4]
mov eax, dword [eax + ETH_DEVICE.bytes_rx] mov eax, dword [eax + ETH_DEVICE.bytes_rx]
mov [esp+20+4], ebx ; TODO: fix this ugly code mov [esp+20+4], ebx ; TODO: fix this ugly code
@ -552,11 +262,6 @@ ETH_API:
.read_mac: .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] movzx ebx, word [eax + ETH_DEVICE.mac]
mov eax, dword [eax + ETH_DEVICE.mac + 2] mov eax, dword [eax + ETH_DEVICE.mac + 2]
mov [esp+20+4], ebx ; TODO: fix this ugly code mov [esp+20+4], ebx ; TODO: fix this ugly code
@ -565,22 +270,24 @@ ETH_API:
.write_mac: .write_mac:
push ecx push ecx
push dx push dx
add eax, ETH_DRV_LIST mov eax, [eax + ETH_DEVICE.set_MAC]
mov eax, [eax]
mov eax, dword [eax + ETH_DEVICE.set_MAC]
call eax call eax
ret ret
.in_queue: .in_queue:
if ETH_QUEUE
add eax, ETH_IN_QUEUE add eax, ETH_IN_QUEUE
mov eax, [eax + queue.size] mov eax, [eax + queue.size]
else
or eax, -1
end if
ret ret
.out_queue: .out_queue:
if QUEUE_BEFORE_SENDING if ETH_QUEUE
add eax, ETH_OUT_QUEUE add eax, ETH_OUT_QUEUE
mov eax, [eax + queue.size] mov eax, [eax + queue.size]
else else
mov eax, -1 or eax, -1
end if end if
ret 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 ;; ;; Distributed under terms of the GNU General Public License ;;
;; ;; ;; ;;
;; ICMP.INC ;; ;; ICMP.INC ;;
@ -130,10 +130,10 @@ ICMP_init:
;----------------------------------------------------------------- ;-----------------------------------------------------------------
; ;
; ICMP_Handler: ; ICMP_input:
; ;
; this procedure will send reply's to ICMP echo's ; 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! ; and insert packets into sockets when needed
; ;
; IN: Pointer to buffer in [esp] ; IN: Pointer to buffer in [esp]
; size of buffer in [esp+4] ; size of buffer in [esp+4]
@ -144,20 +144,22 @@ ICMP_init:
; ;
;----------------------------------------------------------------- ;-----------------------------------------------------------------
align 4 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? cmp byte [edx + ICMP_Packet.Type], ICMP_ECHO ; Is this an echo request?
jne .check_sockets jne .check_sockets
;;; TODO: check checksum! ;;; 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 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 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 cmp edi,-1
je .dump je .dump
inc [ICMP_PACKETS_RX+4*edi] inc [ICMP_PACKETS_RX+4*edi]
@ -207,8 +209,8 @@ ICMP_handler: ;TODO: works only on pure ethernet right now !
pop ecx edx ebx pop ecx edx ebx
mov word [edx + ICMP_Packet.Checksum], ax 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: .try_more:
mov ax , [edx + ICMP_Packet.Identifier] mov ax , [edx + ICMP_Packet.Identifier]
.next_socket: .next_socket:
mov esi, [esi + SOCKET_head.NextPtr] mov esi, [esi + SOCKET.NextPtr]
or esi, esi or esi, esi
jz .dump jz .dump
cmp [esi + SOCKET_head.Type], IP_PROTO_ICMP cmp [esi + SOCKET.Type], IP_PROTO_ICMP
jne .next_socket jne .next_socket
cmp [esi + SOCKET_head.end + IPv4_SOCKET.end + ICMP_SOCKET.Identifier], ax cmp [esi + ICMP_SOCKET.Identifier], ax
jne .next_socket jne .next_socket
call IPv4_dest_to_dev 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 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 call wait_mutex
; Now, assign data to socket. We have socket address in esi. ; 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 add esp, 4
sub edx, esi sub edx, esi
mov edi, edx mov edi, edx
jmp socket_internal_receiver ;;; jmp SOCKET_input
.dump: .dump:
DEBUGF 1,"ICMP_Handler - dumping\n" DEBUGF 1,"ICMP_Handler - dumping\n"
@ -260,59 +262,6 @@ ICMP_handler: ;TODO: works only on pure ethernet right now !
ret 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 :) ; 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 align 4
ICMP_create_packet: ICMP_output:
DEBUGF 1,"Create ICMP Packet\n" DEBUGF 1,"Create ICMP Packet\n"
@ -341,9 +290,7 @@ ICMP_create_packet:
shr edx, 16 shr edx, 16
call IPv4_create_packet call IPv4_create_packet
jz .exit
cmp edi, -1
je .exit
DEBUGF 1,"full icmp packet size: %u\n", edx DEBUGF 1,"full icmp packet size: %u\n", edx
@ -372,7 +319,7 @@ ICMP_create_packet:
and cx , 3 and cx , 3
rep movsb 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] mov ecx, [ebx + ETH_DEVICE.transmit]
push edx edi ecx push edx edi ecx
DEBUGF 1,"Sending ICMP Packet\n" 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 ;; ;; Distributed under terms of the GNU General Public License ;;
;; ;; ;; ;;
;; queue.inc ;; ;; queue.inc ;;
@ -14,7 +14,7 @@
$Revision$ $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: ; 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. ; 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 ;; ;; Distributed under terms of the GNU General Public License ;;
;; ;; ;; ;;
;; STACK.INC ;; ;; 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 __DEBUG_LEVEL__ equ 1 ; this sets the debug level for network part of kernel
uglobal uglobal
last_1sTick db ? net_10ms dd ?
last_1hsTick dd ? net_tmr_count dw ?
endg endg
MAX_NET_DEVICES equ 16 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 MIN_EPHEMERAL_PORT equ 49152
MAX_EPHEMERAL_PORT equ 61000 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_ARP equ 0x0608
ETHER_IPv4 equ 0x0008 ; Reversed from 0800 for intel
;Protocol family
AF_UNSPEC equ 0 AF_UNSPEC equ 0
AF_UNIX equ 1 AF_UNIX equ 1
AF_INET4 equ 2 AF_INET4 equ 2
@ -46,85 +49,88 @@ AF_INET4 equ 2
;AF_BRIDGE equ 7 ;AF_BRIDGE equ 7
;AF_AAL5 equ 8 ;AF_AAL5 equ 8
;AF_X25 equ 9 ;AF_X25 equ 9
;AF_INET6 equ 10 AF_INET6 equ 10
;AF_MAX equ 12 ;AF_MAX equ 12
; Internet protocol numbers
IP_PROTO_IP equ 0 IP_PROTO_IP equ 0
IP_PROTO_ICMP equ 1 IP_PROTO_ICMP equ 1
IP_PROTO_TCP equ 6 IP_PROTO_TCP equ 6
IP_PROTO_UDP equ 17 IP_PROTO_UDP equ 17
; Socket types ; Socket types
SOCK_STREAM = 1 SOCK_STREAM equ 1
SOCK_DGRAM = 2 SOCK_DGRAM equ 2
SOCK_RAW = 3 SOCK_RAW equ 3
TCB_LISTEN equ 1 ; Socket options
TCB_SYN_SENT equ 2 SO_ACCEPTCON equ 1
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
TH_FIN equ 1 shl 0 SOCKET_MAXDATA equ 4096
TH_SYN equ 1 shl 1
TH_RST equ 1 shl 2 ; Network driver types
TH_PUSH equ 1 shl 3 NET_TYPE_ETH equ 1
TH_ACK equ 1 shl 4 NET_TYPE_SLIP equ 2
TH_URG equ 1 shl 5
macro inc_INET reg { virtual at 0
add byte [reg + 3], 1 NET_DEVICE:
adc byte [reg + 2], 0 .type dd ?
adc byte [reg + 1], 0 .end:
adc byte [reg], 0
} 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 { macro pseudo_random reg {
add reg, [esp] add reg, [esp]
rol reg, 5 rol reg, 5
xor reg, [timer_ticks] xor reg, [timer_ticks]
imul reg, 214013 imul reg, 214013
xor reg, 0xdeadbeef xor reg, 0xdeadbeef
rol reg, 9 rol reg, 9
}
pushd reg macro ntohld reg {
mov word [esp], 0x8080 ; kernel heap start addr (os_stack)
xor reg, [esp] rol word reg, 8
add esp, 4 rol dword reg, 16
rol word reg, 8
} }
macro ntohlw reg {
rol word reg, 8
}
include "queue.inc" include "queue.inc"
include "ethernet.inc"
;include "slip.inc"
include "ARP.inc" include "ARP.inc"
include "IPv4.inc" include "IPv4.inc"
include "ethernet.inc"
include "socket.inc"
include "tcp.inc"
include "udp.inc"
include "icmp.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 align 4
stack_init: 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 ETH_init
; call SLIP_init
call IPv4_init call IPv4_init
call ICMP_init
call ARP_init call ARP_init
call UDP_init call UDP_init
call TCP_init call TCP_init
call ICMP_init
call socket_init call socket_init
mov al, 0 ; set up 1s timer mov [net_tmr_count], 0
out 0x70, al
in al, 0x71
mov [last_1sTick], al
ret ret
;----------------------------------------------------------------- ;-----------------------------------------------------------------
; ;
; stack_handler ; stack_handler
; ;
; This function calls all network init procedures ; This function is called in kernel loop
; ;
; IN: / ; IN: /
; OUT: / ; OUT: /
@ -169,41 +184,230 @@ stack_init:
align 4 align 4
stack_handler: stack_handler:
cmp [ETH_RUNNING], 0 cmp [NET_RUNNING], 0
je .exit je .exit
; Test for 10ms tick ; Test for 10ms tick
mov eax, [timer_ticks] mov eax, [timer_ticks]
cmp eax, [last_1hsTick] cmp eax, [net_10ms]
je .exit je .exit
mov [net_10ms], eax
mov [last_1hsTick], eax if ETH_QUEUE
call ETH_handler
call ETH_handler ; handle all queued ethernet packets
if QUEUE_BEFORE_SENDING
call ETH_send_queued call ETH_send_queued
end if end if
call TCP_send_queued call TCP_10ms
.sec_tick: inc [net_tmr_count]
cmp [net_tmr_count], 50
; Test for 1 second tick je .500ms
mov al, 0 cmp [net_tmr_count], 100
out 0x70, al jne .exit
in al, 0x71
cmp al, [last_1sTick]
je .exit
mov [last_1sTick], al
call ARP_decrease_entry_ttls call ARP_decrease_entry_ttls
call IPv4_decrease_fragment_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: .exit:
ret 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 ; checksum_1
@ -333,7 +537,7 @@ sys_network:
cmp ebx, -1 cmp ebx, -1
jne @f jne @f
mov eax, [ETH_RUNNING] mov eax, [NET_RUNNING]
jmp .return jmp .return
@@: @@:
@ -344,12 +548,12 @@ sys_network:
and esi, 0x0000ff00 and esi, 0x0000ff00
shr esi, 6 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 je .doesnt_exist
test bl, bl ; 0 = Get device type (ethernet/token ring/...) test bl, bl ; 0 = Get device type (ethernet/token ring/...)
jnz @f jnz @f
; todo
xor eax, eax xor eax, eax
jmp .return jmp .return
@ -358,7 +562,7 @@ sys_network:
dec bl ; 1 = Get device name dec bl ; 1 = Get device name
jnz @f jnz @f
mov esi, [esi + ETH_DRV_LIST] mov esi, [esi + NET_DRV_LIST]
mov esi, [esi + ETH_DEVICE.name] mov esi, [esi + ETH_DEVICE.name]
mov edi, ecx mov edi, ecx
@ -373,7 +577,7 @@ sys_network:
dec bl ; 2 = Reset the device dec bl ; 2 = Reset the device
jnz @f jnz @f
mov esi, [esi + ETH_DRV_LIST] mov esi, [esi + NET_DRV_LIST]
call [esi + ETH_DEVICE.reset] call [esi + ETH_DEVICE.reset]
jmp .return jmp .return
@ -382,7 +586,7 @@ sys_network:
dec bl ; 3 = Stop driver for this device dec bl ; 3 = Stop driver for this device
jnz @f jnz @f
mov esi, [esi + ETH_DRV_LIST] mov esi, [esi + NET_DRV_LIST]
call [esi + ETH_DEVICE.unload] call [esi + ETH_DEVICE.unload]
jmp .return jmp .return
@ -407,7 +611,7 @@ sys_network:
;---------------------------------------------------------------- ;----------------------------------------------------------------
; ;
; System Function To work with Protocols (75) ; System function to work with protocols (75)
; ;
;---------------------------------------------------------------- ;----------------------------------------------------------------
align 4 align 4
@ -417,8 +621,8 @@ sys_protocols:
mov esi, ebx mov esi, ebx
and esi, 0x0000ff00 and esi, 0x0000ff00
shr esi, 6 shr esi, 6 ; now we have the device num * 4 in esi
cmp dword [esi + ETH_DRV_LIST], 0 ; check if driver is running TODO: check other lists too cmp dword [esi + NET_DRV_LIST], 0 ; check if driver is running
je .doesnt_exist je .doesnt_exist
push .return ; return address (we will be using jumps instead of calls) push .return ; return address (we will be using jumps instead of calls)
@ -441,7 +645,7 @@ sys_protocols:
cmp ax , ETHER_ARP cmp ax , ETHER_ARP
je ARP_API je ARP_API
cmp ax , ETHER cmp ax , 1337
je ETH_API je ETH_API
add esp, 4 ; if we reached here, no function was called, so we need to balance stack 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 ;; ;; Distributed under terms of the GNU General Public License ;;
;; ;; ;; ;;
;; UDP.INC ;; ;; UDP.INC ;;
@ -55,12 +55,11 @@ UDP_init:
ret 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. ; this procedure will inject the udp data diagrams in the application sockets.
; ;
; IN: Pointer to buffer in [esp] ; IN: Pointer to buffer in [esp]
@ -76,23 +75,20 @@ UDP_init:
; ;
;----------------------------------------------------------------- ;-----------------------------------------------------------------
align 4 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: ; First validate, checksum:
cmp [edx + UDP_Packet.Checksum], 0 cmp [edx + UDP_Packet.Checksum], 0
jz .no_checksum 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 edx
push esi edi
push esi
push edi
mov esi, edx 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 pop edx
cmp [edx + UDP_Packet.Checksum], 0 cmp [edx + UDP_Packet.Checksum], 0
@ -108,76 +104,64 @@ UDP_handler:
mov eax, net_sockets mov eax, net_sockets
.try_more: .try_more:
mov si , [edx + UDP_Packet.DestinationPort] ; get the local port from the IP Packet's UDP header mov si , [edx + UDP_Packet.DestinationPort] ; get the local port from the IP Packet's UDP header
rol si , 8
.next_socket: .next_socket:
mov eax, [eax + SOCKET_head.NextPtr] mov eax, [eax + SOCKET.NextPtr]
or eax, eax or eax, eax
jz .dump jz .dump
cmp [eax + SOCKET_head.Domain], AF_INET4 cmp [eax + SOCKET.Domain], AF_INET4
jne .next_socket jne .next_socket
cmp [eax + SOCKET_head.Type], IP_PROTO_UDP cmp [eax + SOCKET.Type], IP_PROTO_UDP
jne .next_socket jne .next_socket
cmp [eax + SOCKET_head.end + IPv4_SOCKET.end + UDP_SOCKET.LocalPort], si cmp [eax + UDP_SOCKET.LocalPort], si
jne .next_socket 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. ;;; TODO: when packet is processed, check more sockets!
; 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
cmp [eax + SOCKET_head.end + IPv4_SOCKET.RemoteIP], edi ; edi is IPv4 destination address cmp [eax + IP_SOCKET.RemoteIP], 0xffffffff
jne .try_more ; Quit if the source IP is not valid, check for more sockets with this IP/PORT combination je @f
cmp [eax + IP_SOCKET.RemoteIP], edi ; edi is the packets source address
jne .try_more
@@:
cmp [eax + UDP_SOCKET.firstpacket], 0
DEBUGF 1,"Remote Ip matches\n"
.ok1:
cmp [eax + SOCKET_head.end + IPv4_SOCKET.end + UDP_SOCKET.firstpacket], 0
jz .updateport jz .updateport
mov si, [edx + UDP_Packet.SourcePort] 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 jne .dump
push ebx push ebx
lea ebx, [eax + SOCKET_head.lock] lea ebx, [eax + SOCKET.lock]
call wait_mutex call wait_mutex
pop ebx pop ebx
.ok2: .updatesock:
inc [UDP_PACKETS_RX]
DEBUGF 1,"Found valid UDP packet for socket %x\n", eax DEBUGF 1,"Found valid UDP packet for socket %x\n", eax
lea esi, [edx + UDP_Packet.Data] lea esi, [edx + UDP_Packet.Data]
movzx ecx, [edx + UDP_Packet.Length] movzx ecx, [edx + UDP_Packet.Length]
rol cx , 8 rol cx , 8
sub cx , UDP_Packet.Data sub cx , UDP_Packet.Data
inc [UDP_PACKETS_RX] jmp SOCKET_input
pop edi
add esp, 4
sub esi, edi
xchg esi, edi
jmp socket_internal_receiver
.updateport: .updateport:
push ebx push ebx
lea ebx, [eax + SOCKET_head.lock] lea ebx, [eax + SOCKET.lock]
call wait_mutex call wait_mutex
pop ebx pop ebx
mov si, [edx + UDP_Packet.SourcePort] mov si, [edx + UDP_Packet.SourcePort]
DEBUGF 1,"Changing remote port to: %x\n", si rol si, 8
mov [eax + SOCKET_head.end + IPv4_SOCKET.end + UDP_SOCKET.RemotePort], si DEBUGF 1,"Changing remote port to: %u\n", si
inc [eax + SOCKET_head.end + IPv4_SOCKET.end + UDP_SOCKET.firstpacket] mov [eax + UDP_SOCKET.RemotePort], si
inc [eax + UDP_SOCKET.firstpacket]
jmp .ok2 jmp .updatesock
.checksum_mismatch: .checksum_mismatch:
@ -202,7 +186,7 @@ UDP_handler:
;----------------------------------------------------------------- ;-----------------------------------------------------------------
; ;
; UDP_socket_send ; UDP_output
; ;
; IN: eax = socket pointer ; IN: eax = socket pointer
; ecx = number of bytes to send ; ecx = number of bytes to send
@ -211,27 +195,31 @@ UDP_handler:
;----------------------------------------------------------------- ;-----------------------------------------------------------------
align 4 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,"UDP_output: socket:%x, bytes: %u, data ptr: %x\n", eax, ecx, esi
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,"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 mov di , IP_PROTO_UDP
sub esp, 8 ; Data ptr and data size will be placed here sub esp, 8 ; Data ptr and data size will be placed here
add ecx, UDP_Packet.Data add ecx, UDP_Packet.Data
; TODO: fill in: dx = fragment id ;;; TODO: fragment id
push edx esi push edx esi
call IPv4_create_packet ; TODO: figure out a way to choose between IPv4 and IPv6 call IPv4_create_packet
cmp edi, -1 jz .fail
je .fail
mov [esp + 8], eax ; pointer to buffer start mov [esp + 8], eax ; pointer to buffer start
mov [esp + 8 + 4], edx ; buffer size mov [esp + 8 + 4], edx ; buffer size
@ -251,7 +239,7 @@ UDP_socket_send:
rep movsb rep movsb
pop ecx edi 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 mov [edi + UDP_Packet.Checksum], 0 ; set it to zero, to calculate checksum
; Checksum ; Checksum
@ -263,10 +251,10 @@ UDP_socket_send:
inc [UDP_PACKETS_TX] inc [UDP_PACKETS_TX]
DEBUGF 1,"Sending UDP Packet to device %x\n", ebx DEBUGF 1,"Sending UDP Packet to device %x\n", ebx
jmp ETH_sender
jmp NET_send
.fail: .fail:
; todo: queue the packet
add esp, 8+8 add esp, 8+8
ret ret
@ -275,7 +263,7 @@ UDP_socket_send:
;----------------------------------------------------------------- ;-----------------------------------------------------------------
; ;
; checksum_udp ; UDP_checksum
; ;
; This is the fast procedure to create or check a UDP header ; 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 ; - To create a new checksum, the checksum field must be set to 0 before computation