forked from KolibriOS/kolibrios
- 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:
parent
321a58ac0f
commit
6a1d621671
@ -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
|
||||
|
@ -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
|
||||
|
@ -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'
|
||||
|
||||
|
@ -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
|
||||
|
||||
|
@ -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
|
||||
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
||||
|
@ -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
|
||||
|
@ -88,7 +88,7 @@ kernel_export \
|
||||
\
|
||||
LFBAddress,\
|
||||
\
|
||||
EthReceiver,\
|
||||
EthRegDev,\
|
||||
EthUnRegDev,\
|
||||
EthStruc2Dev
|
||||
NetRegDev,\
|
||||
NetUnRegDev,\
|
||||
NetPtrToNum,\
|
||||
EthReceiver
|
||||
|
@ -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 ?
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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)
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
||||
|
||||
|
@ -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
|
@ -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"
|
||||
|
@ -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
@ -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
@ -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
|
||||
|
Loading…
Reference in New Issue
Block a user